1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <acpi/acpi_device.h>
4 #include <acpi/acpigen.h>
5 #include <console/console.h>
6 #include <device/i2c_simple.h>
7 #include <device/device.h>
11 #define CS42L42_ACPI_NAME "CRUS"
12 #define CS42L42_ACPI_HID "10134242"
14 static void cs42l42_fill_ssdt(const struct device
*dev
)
16 struct drivers_i2c_cs42l42_config
*config
= dev
->chip_info
;
17 const char *scope
= acpi_device_scope(dev
);
18 const char *path
= acpi_device_path(dev
);
19 struct acpi_i2c i2c
= {
20 .address
= dev
->path
.i2c
.device
,
21 .mode_10bit
= dev
->path
.i2c
.mode_10bit
,
22 .speed
= config
->bus_speed
? : I2C_SPEED_FAST
,
32 acpigen_write_scope(scope
);
33 acpigen_write_device(acpi_device_name(dev
));
34 acpigen_write_name_string("_HID", CS42L42_ACPI_HID
);
35 acpigen_write_name_integer("_UID", 0);
36 acpigen_write_name_string("_DDN", dev
->chip_ops
->name
);
37 acpigen_write_STA(acpi_device_status(dev
));
40 acpigen_write_name("_CRS");
41 acpigen_write_resourcetemplate_header();
42 acpi_device_write_i2c(&i2c
);
43 /* Use either Interrupt() or GpioInt() */
44 if (config
->irq_gpio
.pin_count
)
45 acpi_device_write_gpio(&config
->irq_gpio
);
47 acpi_device_write_interrupt(&config
->irq
);
49 /* for cs42l42reset gpio */
50 if (config
->reset_gpio
.pin_count
)
51 acpi_device_write_gpio(&config
->reset_gpio
);
53 acpigen_write_resourcetemplate_footer();
55 /* AAD Child Device Properties */
56 dsd
= acpi_dp_new_table("_DSD");
57 if (config
->irq_gpio
.pin_count
)
58 acpi_dp_add_gpio(dsd
, "irq-gpios", path
,
59 gpio_index
++, /* Index = 0 */
60 0, /* Pin = 0 (There is a single pin in the GPIO resource). */
61 config
->irq_gpio
.active_low
);
62 if (config
->reset_gpio
.pin_count
)
63 acpi_dp_add_gpio(dsd
, "reset-gpios", path
,
64 gpio_index
++, /* Index = 0 or 1 (if irq gpio is written). */
65 0, /* Pin = 0 (There is a single pin in the GPIO resource). */
66 config
->reset_gpio
.active_low
);
67 acpi_dp_add_integer(dsd
, "cirrus,ts-inv", config
->ts_inv
? 1 : 0);
68 acpi_dp_add_integer(dsd
, "cirrus,ts-dbnc-rise", config
->ts_dbnc_rise
);
69 acpi_dp_add_integer(dsd
, "cirrus,ts-dbnc-fall", config
->ts_dbnc_fall
);
70 acpi_dp_add_integer(dsd
, "cirrus,btn-det-init-dbnce", config
->btn_det_init_dbnce
);
72 if (config
->btn_det_init_dbnce
> 200) {
73 printk(BIOS_ERR
, "%s: Incorrect btn_det_init_dbnce(%d). Using default of 100ms\n",
74 __func__
, config
->btn_det_init_dbnce
);
75 config
->btn_det_init_dbnce
= 100;
78 acpi_dp_add_integer(dsd
, "cirrus,btn-det-event-dbnce", config
->btn_det_event_dbnce
);
80 if (config
->btn_det_event_dbnce
> 100) {
81 printk(BIOS_ERR
, "%s: Incorrect btn_det_event_dbnce(%d). Using default of 10ms\n",
82 __func__
, config
->btn_det_event_dbnce
);
83 config
->btn_det_event_dbnce
= 10;
86 acpi_dp_add_integer_array(dsd
, "cirrus,bias-lvls", config
->bias_lvls
, 4);
87 acpi_dp_add_integer(dsd
, "cirrus,hs-bias-ramp-rate", config
->hs_bias_ramp_rate
);
88 if (config
->hs_bias_sense_disable
)
89 acpi_dp_add_integer(dsd
, "cirrus,hs-bias-sense-disable", 1);
91 /* Write Device Property Hierarchy */
94 acpigen_pop_len(); /* Device */
95 acpigen_pop_len(); /* Scope */
97 printk(BIOS_INFO
, "%s: %s address 0%xh irq %d\n",
98 acpi_device_path(dev
), dev
->chip_ops
->name
,
99 dev
->path
.i2c
.device
, config
->irq
.pin
);
102 static const char *cs42l42_acpi_name(const struct device
*dev
)
104 return CS42L42_ACPI_NAME
;
107 static struct device_operations cs42l42_ops
= {
108 .read_resources
= noop_read_resources
,
109 .set_resources
= noop_set_resources
,
110 .acpi_name
= cs42l42_acpi_name
,
111 .acpi_fill_ssdt
= cs42l42_fill_ssdt
,
114 static void cs42l42_enable(struct device
*dev
)
116 dev
->ops
= &cs42l42_ops
;
119 struct chip_operations drivers_i2c_cs42l42_ops
= {
120 .name
= "Cirrus Logic CS42l42 Audio Codec",
121 .enable_dev
= cs42l42_enable