1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <acpi/acpi_device.h>
5 #include <acpi/acpigen.h>
6 #include <console/console.h>
7 #include <device/i2c_simple.h>
8 #include <device/device.h>
13 #define CS35L53_ACPI_HID "CSC3541"
15 static void cs35l53_fill_ssdt(const struct device
*dev
)
17 struct drivers_i2c_cs35l53_config
*config
= dev
->chip_info
;
18 const char *scope
= acpi_device_scope(dev
);
19 const char *path
= acpi_device_path(dev
);
20 struct acpi_i2c i2c
= {
21 .address
= dev
->path
.i2c
.device
,
22 .mode_10bit
= dev
->path
.i2c
.mode_10bit
,
23 .speed
= config
->bus_speed
? : I2C_SPEED_FAST
,
33 acpigen_write_scope(scope
);
34 acpigen_write_device(acpi_device_name(dev
));
35 acpigen_write_name_string("_HID", CS35L53_ACPI_HID
);
36 acpigen_write_name_integer("_UID", config
->uid
);
37 if (config
->desc
== NULL
)
38 acpigen_write_name_string("_DDN", dev
->chip_ops
->name
);
40 acpigen_write_name_string("_DDN", config
->desc
);
41 acpigen_write_name_string("_SUB", config
->sub
);
42 acpigen_write_STA(acpi_device_status(dev
));
45 acpigen_write_name("_CRS");
46 acpigen_write_resourcetemplate_header();
47 acpi_device_write_i2c(&i2c
);
48 /* Use either Interrupt() or GpioInt() */
49 if (config
->irq_gpio
.pin_count
)
50 acpi_device_write_gpio(&config
->irq_gpio
);
52 acpi_device_write_interrupt(&config
->irq
);
54 /* for cs35l53 reset gpio */
55 if (config
->reset_gpio
.pin_count
)
56 acpi_device_write_gpio(&config
->reset_gpio
);
58 acpigen_write_resourcetemplate_footer();
60 /* Add Child Device Properties */
61 dsd
= acpi_dp_new_table("_DSD");
62 if (config
->irq_gpio
.pin_count
)
63 acpi_dp_add_gpio(dsd
, "irq-gpios", path
,
64 gpio_index
++, /* Index = 0 */
65 0, /* Pin = 0 (There is a single pin in the GPIO resource). */
66 config
->irq_gpio
.active_low
);
67 if (config
->reset_gpio
.pin_count
)
68 acpi_dp_add_gpio(dsd
, "reset-gpios", path
,
69 gpio_index
++, /* Index = 0 or 1 (if irq gpio is written). */
70 0, /* Pin = 0 (There is a single pin in the GPIO resource). */
71 config
->reset_gpio
.active_low
);
73 acpi_dp_add_integer(dsd
, "cirrus,boost-type", config
->boost_type
);
75 switch (config
->boost_type
) {
77 if ((config
->boost_peak_milliamp
> 4500) ||
78 (config
->boost_peak_milliamp
< 1600) ||
79 (config
->boost_peak_milliamp
% 50)) {
81 "%s: Incorrect boost_peak_milliamp(%d). Using default of 4500 mA\n",
82 __func__
, config
->boost_peak_milliamp
);
83 config
->boost_peak_milliamp
= 4500;
85 acpi_dp_add_integer(dsd
, "cirrus,boost-peak-milliamp",
86 config
->boost_peak_milliamp
);
87 acpi_dp_add_integer(dsd
, "cirrus,boost-ind-nanohenry",
88 config
->boost_ind_nanohenry
);
89 acpi_dp_add_integer(dsd
, "cirrus,boost-cap-microfarad",
90 config
->boost_cap_microfarad
);
93 config
->gpio1_output_enable
= true;
94 config
->gpio1_src_select
= GPIO1_SRC_GPIO
;
100 acpi_dp_add_integer(dsd
, "cirrus,asp-sdout-hiz", config
->asp_sdout_hiz
);
101 acpi_dp_add_integer(dsd
, "cirrus,gpio1-polarity-invert",
102 config
->gpio1_polarity_invert
);
103 acpi_dp_add_integer(dsd
, "cirrus,gpio1-output-enable",
104 config
->gpio1_output_enable
);
105 acpi_dp_add_integer(dsd
, "cirrus,gpio1-src-select", config
->gpio1_src_select
);
106 acpi_dp_add_integer(dsd
, "cirrus,gpio2-polarity-invert",
107 config
->gpio2_polarity_invert
);
108 acpi_dp_add_integer(dsd
, "cirrus,gpio2-output-enable",
109 config
->gpio2_output_enable
);
110 acpi_dp_add_integer(dsd
, "cirrus,gpio2-src-select", config
->gpio2_src_select
);
112 /* Write Device Property Hierarchy */
115 acpigen_pop_len(); /* Device */
116 acpigen_pop_len(); /* Scope */
118 printk(BIOS_INFO
, "%s: %s address 0%xh irq %d\n",
119 acpi_device_path(dev
), dev
->chip_ops
->name
,
120 dev
->path
.i2c
.device
, config
->irq
.pin
);
123 static const char *cs35l53_acpi_name(const struct device
*dev
)
125 struct drivers_i2c_cs35l53_config
*config
= dev
->chip_info
;
126 static char name
[ACPI_NAME_BUFFER_SIZE
];
131 snprintf(name
, sizeof(name
), "D%03.3X", dev
->path
.i2c
.device
);
135 static struct device_operations cs35l53_ops
= {
136 .read_resources
= noop_read_resources
,
137 .set_resources
= noop_set_resources
,
138 .acpi_name
= cs35l53_acpi_name
,
139 .acpi_fill_ssdt
= cs35l53_fill_ssdt
,
142 static void cs35l53_enable(struct device
*dev
)
144 dev
->ops
= &cs35l53_ops
;
147 struct chip_operations drivers_i2c_cs35l53_ops
= {
148 .name
= "Cirrus Logic CS35L53 Audio Codec",
149 .enable_dev
= cs35l53_enable