xref: /linux/sound/hda/codecs/side-codecs/aw88399_hda.c (revision e5c91aac491def6ab3f90c4cc246e3fcb0f8f058)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // AW88399 HDA side codec driver
4 //
5 // Based on cs35l41_hda.c and aw88399.c
6 //
7 
8 #include <linux/acpi.h>
9 #include <linux/gpio/consumer.h>
10 #include <linux/i2c.h>
11 #include <linux/module.h>
12 #include <linux/mutex.h>
13 #include <linux/pm_runtime.h>
14 #include <linux/string.h>
15 #include <sound/hda_codec.h>
16 #include "../generic.h"
17 #include "hda_component.h"
18 #include "aw88399_hda.h"
19 
20 #define AW88399_HDA_I2C_BASE_ADDR	0x34
21 
22 static void aw88399_hda_playback_hook(struct device *dev, int action)
23 {
24 	struct aw88399_hda *aw88399 = dev_get_drvdata(dev);
25 	struct aw88399 *core = aw88399->core;
26 	int ret = 0;
27 
28 	dev_dbg(aw88399->dev, "Playback action: %d\n", action);
29 
30 	switch (action) {
31 	case HDA_GEN_PCM_ACT_OPEN:
32 		pm_runtime_get_sync(dev);
33 		aw88399->playing = true;
34 		break;
35 	case HDA_GEN_PCM_ACT_PREPARE:
36 		if (core)
37 			aw88399_start(core, AW88399_SYNC_START);
38 		break;
39 	case HDA_GEN_PCM_ACT_CLEANUP:
40 		if (aw88399->aw_dev)
41 			ret = aw88399_stop(aw88399->aw_dev);
42 		if (ret)
43 			dev_err(aw88399->dev, "Failed to stop amplifier: %d\n", ret);
44 		break;
45 	case HDA_GEN_PCM_ACT_CLOSE:
46 		if (aw88399->aw_dev)
47 			aw88399_stop(aw88399->aw_dev);
48 		aw88399->playing = false;
49 		pm_runtime_mark_last_busy(dev);
50 		pm_runtime_put_autosuspend(dev);
51 		break;
52 	default:
53 		dev_warn(aw88399->dev, "Unsupported action: %d\n", action);
54 		break;
55 	}
56 }
57 
58 static int aw88399_hda_bind(struct device *dev, struct device *master, void *master_data)
59 {
60 	struct aw88399_hda *aw88399 = dev_get_drvdata(dev);
61 	struct hda_component_parent *parent = master_data;
62 	struct hda_component *comp;
63 
64 	comp = hda_component_from_index(parent, aw88399->index);
65 	if (!comp)
66 		return -EINVAL;
67 
68 	if (comp->dev)
69 		return -EBUSY;
70 
71 	comp->dev = dev;
72 
73 	strscpy(comp->name, dev_name(dev), sizeof(comp->name));
74 
75 	comp->playback_hook = aw88399_hda_playback_hook;
76 
77 	dev_info(aw88399->dev,
78 		 "AW88399 Bound - SSID: %s, channel: %d\n",
79 		 aw88399->acpi_subsystem_id, aw88399->channel);
80 
81 	return 0;
82 }
83 
84 static void aw88399_hda_unbind(struct device *dev, struct device *master, void *master_data)
85 {
86 	struct aw88399_hda *aw88399 = dev_get_drvdata(dev);
87 	struct hda_component_parent *parent = master_data;
88 	struct hda_component *comp;
89 
90 	comp = hda_component_from_index(parent, aw88399->index);
91 	if (comp && (comp->dev == dev))
92 		memset(comp, 0, sizeof(*comp));
93 
94 	dev_dbg(aw88399->dev, "Unbound from HDA codec\n");
95 }
96 
97 static const struct component_ops aw88399_hda_comp_ops = {
98 	.bind = aw88399_hda_bind,
99 	.unbind = aw88399_hda_unbind,
100 };
101 
102 static int aw88399_hda_index_from_i2c(struct aw88399_hda *aw88399)
103 {
104 	return to_i2c_client(aw88399->dev)->addr - AW88399_HDA_I2C_BASE_ADDR;
105 }
106 
107 static int aw88399_hda_init(struct aw88399_hda *aw88399)
108 {
109 	struct device *dev = aw88399->dev;
110 	struct i2c_client *i2c = to_i2c_client(dev);
111 	struct aw88399 *core;
112 	int ret;
113 
114 	core = devm_kzalloc(dev, sizeof(*core), GFP_KERNEL);
115 	if (!core)
116 		return -ENOMEM;
117 
118 	mutex_init(&core->lock);
119 	core->reset_gpio = aw88399->reset_gpio;
120 	core->regmap = aw88399->regmap;
121 	core->bsts_unreliable = aw88399->bsts_unreliable;
122 
123 	aw88399_hw_reset(core);
124 
125 	ret = aw88399_init(core, i2c, aw88399->regmap);
126 	if (ret)
127 		return ret;
128 
129 	/* Set channel BEFORE loading firmware so ACF parser sees correct value */
130 	if (core->aw_pa)
131 		aw88399_dev_set_channel(core, aw88399->channel);
132 
133 	ret = aw88399_request_firmware_file(core);
134 	if (ret)
135 		return ret;
136 
137 	aw88399->core = core;
138 	aw88399->aw_dev = core->aw_pa;
139 
140 	return 0;
141 }
142 
143 static int aw88399_swap_channels(struct aw88399_hda *aw88399)
144 {
145 	/*
146 	 * Certain Lenovo Legion laptops have their
147 	 * I2C wiring reversed: 0x34 is physically the right speaker,
148 	 * 0x35 is the left. Swap channels to correct L/R assignment.
149 	 * This is a model-specific hardware wiring issue, not a driver bug.
150 	 */
151 	aw88399->channel = 1 - aw88399->channel;
152 	dev_dbg(aw88399->dev,
153 		"Channel swap applied: index %d -> channel %d\n",
154 		aw88399->index, aw88399->channel);
155 	return 0;
156 }
157 
158 static int aw88399_skip_bsts_check(struct aw88399_hda *aw88399)
159 {
160 	/*
161 	 * BSTS (boost-finished) status bit does not reliably report on
162 	 * some hardware. On certain Lenovo Legion laptops, both amps
163 	 * report BSTS=0 (boost not finished) during normal playback
164 	 * despite clean audio output. Skip BSTS in the startup status
165 	 * check to avoid false init failures.
166 	 */
167 	aw88399->bsts_unreliable = true;
168 	dev_dbg(aw88399->dev, "BSTS status check disabled\n");
169 	return 0;
170 }
171 
172 static int aw88399_apply_legion_quirks(struct aw88399_hda *aw88399)
173 {
174 	aw88399_swap_channels(aw88399);
175 	aw88399_skip_bsts_check(aw88399);
176 	return 0;
177 }
178 
179 struct aw88399_prop_model {
180 	const char *ssid;
181 	int (*apply_prop)(struct aw88399_hda *aw88399);
182 };
183 
184 static const struct aw88399_prop_model aw88399_prop_model_table[] = {
185 	{ "17AA3906", aw88399_apply_legion_quirks },
186 	{ "17AA3907", aw88399_apply_legion_quirks },
187 	{ "17AA3927", aw88399_apply_legion_quirks },
188 	{ "17AA3928", aw88399_apply_legion_quirks },
189 	{ "17AA3936", aw88399_apply_legion_quirks },
190 	{ "17AA3937", aw88399_apply_legion_quirks },
191 	{ "17AA3938", aw88399_apply_legion_quirks },
192 	{ "17AA3939", aw88399_apply_legion_quirks },
193 	{ }
194 };
195 
196 static int aw88399_hda_acpi_probe(struct aw88399_hda *aw88399)
197 {
198 	struct acpi_device *adev;
199 	const char *sub;
200 	const struct aw88399_prop_model *model;
201 
202 	aw88399->index = aw88399_hda_index_from_i2c(aw88399);
203 	aw88399->channel = aw88399->index;
204 	aw88399->acpi_subsystem_id = NULL;
205 
206 	adev = acpi_dev_get_first_match_dev("AWDZ8399", NULL, -1);
207 	if (!adev) {
208 		dev_err(aw88399->dev, "Failed to find an ACPI device for AWDZ8399\n");
209 		return -ENODEV;
210 	}
211 
212 	struct device *physdev __free(put_device) =
213 		get_device(acpi_get_first_physical_node(adev));
214 	acpi_dev_put(adev);
215 	if (!physdev)
216 		return -ENODEV;
217 
218 	sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev));
219 	if (IS_ERR_OR_NULL(sub))
220 		return 0;
221 
222 	aw88399->acpi_subsystem_id = devm_kstrdup(aw88399->dev, sub, GFP_KERNEL);
223 	kfree(sub);
224 	if (!aw88399->acpi_subsystem_id)
225 		return -ENOMEM;
226 
227 	for (model = aw88399_prop_model_table; model->ssid; model++) {
228 		if (!strcasecmp(model->ssid, aw88399->acpi_subsystem_id)) {
229 			dev_info(aw88399->dev,
230 				 "Applying properties for SSID %s\n",
231 				 aw88399->acpi_subsystem_id);
232 			return model->apply_prop(aw88399);
233 		}
234 	}
235 
236 	return 0;
237 }
238 
239 int aw88399_hda_probe(struct device *dev, struct regmap *regmap)
240 {
241 	struct aw88399_hda *aw88399;
242 	int ret;
243 
244 	aw88399 = devm_kzalloc(dev, sizeof(*aw88399), GFP_KERNEL);
245 	if (!aw88399)
246 		return -ENOMEM;
247 
248 	if (IS_ERR(regmap))
249 		return dev_err_probe(dev, PTR_ERR(regmap), "Failed to obtain regmap\n");
250 
251 	aw88399->dev = dev;
252 	aw88399->regmap = regmap;
253 	dev_set_drvdata(dev, aw88399);
254 
255 	aw88399->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
256 	if (IS_ERR(aw88399->reset_gpio))
257 		return dev_err_probe(dev, PTR_ERR(aw88399->reset_gpio),
258 				     "Failed to get reset GPIO\n");
259 
260 	ret = aw88399_hda_acpi_probe(aw88399);
261 	if (ret)
262 		return dev_err_probe(dev, ret, "ACPI probe failed\n");
263 
264 	ret = aw88399_hda_init(aw88399);
265 	if (ret)
266 		return dev_err_probe(dev, ret, "Chip initialization failed\n");
267 
268 	/* Enable runtime PM */
269 	pm_runtime_set_autosuspend_delay(dev, 3000);
270 	pm_runtime_use_autosuspend(dev);
271 	pm_runtime_mark_last_busy(dev);
272 	pm_runtime_set_active(dev);
273 	pm_runtime_enable(dev);
274 
275 	ret = component_add(dev, &aw88399_hda_comp_ops);
276 	if (ret) {
277 		pm_runtime_disable(dev);
278 		return dev_err_probe(dev, ret, "Failed to register component\n");
279 	}
280 
281 	dev_info(dev, "AW88399 HDA side codec registered successfully\n");
282 
283 	return 0;
284 }
285 EXPORT_SYMBOL_NS_GPL(aw88399_hda_probe, "SND_HDA_SCODEC_AW88399");
286 
287 void aw88399_hda_remove(struct device *dev)
288 {
289 	struct aw88399_hda *aw88399 = dev_get_drvdata(dev);
290 
291 	pm_runtime_disable(dev);
292 
293 	if (aw88399->aw_dev)
294 		aw88399_stop(aw88399->aw_dev);
295 
296 	component_del(dev, &aw88399_hda_comp_ops);
297 
298 	dev_dbg(aw88399->dev, "AW88399 HDA side codec removed\n");
299 }
300 EXPORT_SYMBOL_NS_GPL(aw88399_hda_remove, "SND_HDA_SCODEC_AW88399");
301 
302 static int aw88399_hda_runtime_suspend(struct device *dev)
303 {
304 	struct aw88399_hda *aw88399 = dev_get_drvdata(dev);
305 
306 	dev_dbg(aw88399->dev, "Runtime suspend\n");
307 
308 	if (aw88399->aw_dev && aw88399->playing)
309 		aw88399_stop(aw88399->aw_dev);
310 
311 	return 0;
312 }
313 
314 static int aw88399_hda_runtime_resume(struct device *dev)
315 {
316 	struct aw88399_hda *aw88399 = dev_get_drvdata(dev);
317 
318 	dev_dbg(aw88399->dev, "Runtime resume\n");
319 
320 	if (aw88399->core && aw88399->aw_dev && aw88399->playing)
321 		aw88399_start(aw88399->core, AW88399_SYNC_START);
322 
323 	return 0;
324 }
325 
326 static int aw88399_hda_system_suspend(struct device *dev)
327 {
328 	struct aw88399_hda *aw88399 = dev_get_drvdata(dev);
329 	int ret;
330 
331 	dev_dbg(aw88399->dev, "System suspend\n");
332 
333 	if (aw88399->aw_dev && aw88399->playing)
334 		aw88399_stop(aw88399->aw_dev);
335 
336 	if (aw88399->core)
337 		aw88399->core->fw_needs_reload = true;
338 
339 	ret = pm_runtime_force_suspend(dev);
340 	if (ret)
341 		dev_err(aw88399->dev, "Runtime force suspend failed: %d\n", ret);
342 
343 	return ret;
344 }
345 
346 static int aw88399_hda_system_resume(struct device *dev)
347 {
348 	struct aw88399_hda *aw88399 = dev_get_drvdata(dev);
349 	int ret;
350 
351 	dev_dbg(aw88399->dev, "System resume\n");
352 
353 	if (aw88399->aw_dev)
354 		aw88399_hw_reset(aw88399->core);
355 
356 	ret = pm_runtime_force_resume(dev);
357 	if (ret)
358 		dev_err(aw88399->dev, "Runtime force resume failed: %d\n", ret);
359 
360 	return ret;
361 }
362 
363 const struct dev_pm_ops aw88399_hda_pm_ops = {
364 	RUNTIME_PM_OPS(aw88399_hda_runtime_suspend, aw88399_hda_runtime_resume, NULL)
365 	SYSTEM_SLEEP_PM_OPS(aw88399_hda_system_suspend, aw88399_hda_system_resume)
366 };
367 EXPORT_SYMBOL_NS_GPL(aw88399_hda_pm_ops, "SND_HDA_SCODEC_AW88399");
368 
369 MODULE_DESCRIPTION("AW88399 HDA driver");
370 MODULE_AUTHOR("Yakov Till <yakov.till@gmail.com>");
371 MODULE_AUTHOR("Marco Giunta <marco_giunta@outlook.it>");
372 MODULE_LICENSE("GPL");
373 MODULE_FIRMWARE("aw88399_acf.bin");
374