blob: 7a18b986294fa6895d4e89d9ecb91f2fb1f7601d [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Duncan Laurie7db15092016-05-11 11:27:47 -07002
Furquan Shaikh76cedd22020-05-02 10:24:23 -07003#include <acpi/acpi_device.h>
4#include <acpi/acpigen.h>
Duncan Laurie7db15092016-05-11 11:27:47 -07005#include <console/console.h>
6#include <device/device.h>
7#include <device/path.h>
8#include <gpio.h>
Duncan Laurie7db15092016-05-11 11:27:47 -07009#include "chip.h"
10
Duncan Laurie7db15092016-05-11 11:27:47 -070011#define MAX98357A_ACPI_NAME "MAXM"
Duncan Laurie7db15092016-05-11 11:27:47 -070012
Furquan Shaikh7536a392020-04-24 21:59:21 -070013static void max98357a_fill_ssdt(const struct device *dev)
Duncan Laurie7db15092016-05-11 11:27:47 -070014{
15 struct drivers_generic_max98357a_config *config = dev->chip_info;
Duncan Laurie366cd212016-06-29 22:34:01 -070016 const char *path;
Duncan Laurieffc99902016-07-02 19:56:06 -070017 struct acpi_dp *dp;
Duncan Laurie7db15092016-05-11 11:27:47 -070018
Karthikeyan Ramasubramaniand1c0f952020-11-02 16:26:52 -070019 if (!config)
Duncan Laurie7db15092016-05-11 11:27:47 -070020 return;
21
Jacob Garberbdcb4d32019-05-27 17:10:24 -060022 const char *scope = acpi_device_scope(dev);
23 const char *name = acpi_device_name(dev);
24 if (!scope || !name)
25 return;
26
Aamir Bohraa1c82c52020-03-16 18:57:48 +053027 if (!config->hid) {
28 printk(BIOS_ERR, "%s: ERROR: _HID required\n", dev_path(dev));
29 return;
30 }
31
Raul E Rangel066a9af2020-06-02 10:47:27 -060032 /* Device */
33 acpigen_write_scope(scope);
34 acpigen_write_device(name);
35
Aamir Bohraa1c82c52020-03-16 18:57:48 +053036 acpigen_write_name_string("_HID", config->hid);
Duncan Laurie7db15092016-05-11 11:27:47 -070037 acpigen_write_name_integer("_UID", 0);
38 acpigen_write_name_string("_DDN", dev->chip_ops->name);
Hung-Te Linb4be50c2018-09-10 10:55:49 +080039 acpigen_write_STA(acpi_device_status(dev));
Duncan Laurie7db15092016-05-11 11:27:47 -070040
41 /* Resources */
42 acpigen_write_name("_CRS");
43 acpigen_write_resourcetemplate_header();
44 acpi_device_write_gpio(&config->sdmode_gpio);
45 acpigen_write_resourcetemplate_footer();
46
47 /* _DSD for devicetree properties */
Duncan Laurie7db15092016-05-11 11:27:47 -070048 /* This points to the first pin in the first gpio entry in _CRS */
Duncan Laurie366cd212016-06-29 22:34:01 -070049 path = acpi_device_path(dev);
Duncan Laurieffc99902016-07-02 19:56:06 -070050 dp = acpi_dp_new_table("_DSD");
Furquan Shaikh028200f2016-10-04 10:53:32 -070051 acpi_dp_add_gpio(dp, "sdmode-gpio", path, 0, 0,
Furquan Shaikhd2d5e442020-07-01 01:37:13 -070052 config->sdmode_gpio.active_low);
Duncan Laurieffc99902016-07-02 19:56:06 -070053 acpi_dp_add_integer(dp, "sdmode-delay", config->sdmode_delay);
54 acpi_dp_write(dp);
Duncan Laurie7db15092016-05-11 11:27:47 -070055
56 acpigen_pop_len(); /* Device */
57 acpigen_pop_len(); /* Scope */
58
59 printk(BIOS_INFO, "%s: %s\n", path, dev->chip_ops->name);
60}
61
Aaron Durbinaa090cb2017-09-13 16:01:52 -060062static const char *max98357a_acpi_name(const struct device *dev)
Duncan Laurie7db15092016-05-11 11:27:47 -070063{
64 return MAX98357A_ACPI_NAME;
65}
Duncan Laurie7db15092016-05-11 11:27:47 -070066
67static struct device_operations max98357a_ops = {
Nico Huber2f8ba692020-04-05 14:05:24 +020068 .read_resources = noop_read_resources,
69 .set_resources = noop_set_resources,
Nico Huber68680dd2020-03-31 17:34:52 +020070 .acpi_name = max98357a_acpi_name,
71 .acpi_fill_ssdt = max98357a_fill_ssdt,
Duncan Laurie7db15092016-05-11 11:27:47 -070072};
73
74static void max98357a_enable(struct device *dev)
75{
76 struct drivers_generic_max98357a_config *config = dev->chip_info;
77
78 /* Check if device is present by reading GPIO */
79 if (config->device_present_gpio) {
80 int present = gpio_get(config->device_present_gpio);
81 present ^= config->device_present_gpio_invert;
82
83 printk(BIOS_INFO, "%s is %spresent\n",
84 dev->chip_ops->name, present ? "" : "not ");
85
86 if (!present) {
87 dev->enabled = 0;
88 return;
89 }
90 }
91
92 dev->ops = &max98357a_ops;
93}
94
95struct chip_operations drivers_generic_max98357a_ops = {
96 CHIP_NAME("Maxim Integrated 98357A Amplifier")
Elyes HAOUAS2aa3b162018-11-27 17:02:10 +010097 .enable_dev = max98357a_enable
Duncan Laurie7db15092016-05-11 11:27:47 -070098};