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/device.h>
11 #define RT5645_ACPI_NAME "RT58"
12 #define RT5645_ACPI_HID "10EC5650"
14 #define RT5645_DP_INT(key, val) \
15 acpi_dp_add_integer(dp, "realtek," key, (val))
17 static void rt5645_fill_ssdt(const struct device
*dev
)
19 struct drivers_i2c_rt5645_config
*config
= dev
->chip_info
;
21 const char *scope
= acpi_device_scope(dev
);
22 int cbj_sleeve_index
= -1, irq_gpio_index
= -1, hp_detect_index
= -1;
23 struct acpi_i2c i2c
= {
24 .address
= dev
->path
.i2c
.device
,
25 .mode_10bit
= dev
->path
.i2c
.mode_10bit
,
26 .speed
= config
->bus_speed
? : I2C_SPEED_FAST
,
35 const char *name
= acpi_device_name(dev
);
40 acpigen_write_scope(scope
);
41 acpigen_write_device(name
);
44 acpigen_write_name_string("_HID", config
->hid
);
46 acpigen_write_name_string("_HID", RT5645_ACPI_HID
);
47 acpigen_write_name_integer("_UID", 0);
49 acpigen_write_name_string("_DDN", config
->desc
);
50 /* Hide the device because of Microsoft Windows */
51 acpigen_write_STA(ACPI_STATUS_DEVICE_HIDDEN_ON
);
54 acpigen_write_name("_CRS");
55 acpigen_write_resourcetemplate_header();
56 acpi_device_write_i2c(&i2c
);
58 /* Use either Interrupt() or GpioInt() */
59 if (config
->irq_gpio
.pin_count
)
60 irq_gpio_index
= acpi_device_write_dsd_gpio(&config
->irq_gpio
,
63 acpi_device_write_interrupt(&config
->irq
);
65 /* Add I2C GPIO index */
66 cbj_sleeve_index
= acpi_device_write_dsd_gpio(&config
->cbj_sleeve
,
68 hp_detect_index
= acpi_device_write_dsd_gpio(&config
->hp_detect
,
70 acpigen_write_resourcetemplate_footer();
72 /* _DSD for devicetree properties */
73 /* This points to the first pin in the first gpio entry in _CRS */
74 path
= acpi_device_path(dev
);
75 dp
= acpi_dp_new_table("_DSD");
76 if (config
->irq_gpio
.pin_count
)
77 acpi_dp_add_gpio(dp
, "irq-gpios", path
, irq_gpio_index
, 0,
78 config
->irq_gpio
.active_low
);
79 if (config
->cbj_sleeve
.pin_count
)
80 acpi_dp_add_gpio(dp
, "cbj-sleeve-gpios", path
, cbj_sleeve_index
, 0,
81 config
->cbj_sleeve
.active_low
);
82 if (config
->hp_detect
.pin_count
)
83 acpi_dp_add_gpio(dp
, "hp-detect-gpios", path
, hp_detect_index
, 0,
84 config
->hp_detect
.active_low
);
85 RT5645_DP_INT("jd-mode", config
->jd_mode
);
88 acpigen_pop_len(); /* Device */
89 acpigen_pop_len(); /* Scope */
91 printk(BIOS_INFO
, "%s: %s address 0%xh\n", path
,
92 config
->desc
? : dev
->chip_ops
->name
, dev
->path
.i2c
.device
);
95 static const char *rt5645_acpi_name(const struct device
*dev
)
97 struct drivers_i2c_rt5645_config
*config
= dev
->chip_info
;
102 snprintf(name
, sizeof(name
), "D%03.3X", dev
->path
.i2c
.device
);
106 static struct device_operations rt5645_ops
= {
107 .read_resources
= noop_read_resources
,
108 .set_resources
= noop_set_resources
,
109 .acpi_name
= rt5645_acpi_name
,
110 .acpi_fill_ssdt
= rt5645_fill_ssdt
,
113 static void rt5645_enable(struct device
*dev
)
115 dev
->ops
= &rt5645_ops
;
118 struct chip_operations drivers_i2c_rt5645_ops
= {
119 .name
= "ASoC RT5645 Codec driver",
120 .enable_dev
= rt5645_enable