1 /*
2 * ALSA SoC Texas Instruments TAS2770 20-W Digital Input Mono Class-D
3 * Audio Amplifier with Speaker I/V Sense
4 *
5 * Copyright (C) 2016 Texas Instruments, Inc.
6 *
7 * Author: saiprasad
8 *
9 * This package is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 */
18 #ifdef CONFIG_TAS2770_REGMAP
20 #define DEBUG
21 #include <linux/module.h>
22 #include <linux/moduleparam.h>
23 #include <linux/err.h>
24 #include <linux/init.h>
25 #include <linux/delay.h>
26 #include <linux/pm.h>
27 #include <linux/i2c.h>
28 #include <linux/gpio.h>
29 #include <linux/regulator/consumer.h>
30 #include <linux/firmware.h>
31 #include <linux/regmap.h>
32 #include <linux/of.h>
33 #include <linux/of_gpio.h>
34 #include <linux/slab.h>
35 #include <sound/soc.h>
37 #include "tas2770.h"
38 #include "tas2770-codec.h"
40 static const struct reg_default tas2770_reg_defaults[] = {
41 { TAS2770_Page, 0x00 },
42 { TAS2770_SoftwareReset, 0x00 },
43 { TAS2770_PowerControl, 0x0e },
44 { TAS2770_PlaybackConfigurationReg0, 0x10 },
45 { TAS2770_PlaybackConfigurationReg1, 0x01 },
46 { TAS2770_PlaybackConfigurationReg2, 0x00 },
47 { TAS2770_MiscConfigurationReg0, 0x07 },
48 { TAS2770_TDMConfigurationReg1, 0x02 },
49 { TAS2770_TDMConfigurationReg2, 0x0a },
50 { TAS2770_TDMConfigurationReg3, 0x10 },
51 { TAS2770_InterruptMaskReg0, 0xfc },
52 { TAS2770_InterruptMaskReg1, 0xb1 },
53 { TAS2770_InterruptConfiguration, 0x05 },
54 { TAS2770_MiscIRQ, 0x81 },
55 { TAS2770_ClockConfiguration, 0x0c },
57 };
59 static bool tas2770_volatile(struct device *dev, unsigned int reg)
60 {
61 switch (reg) {
62 case TAS2770_Page: /* regmap implementation requires this */
63 case TAS2770_SoftwareReset: /* always clears after write */
64 case TAS2770_PowerControl:
65 case TAS2770_BrownOutPreventionReg0:/* has a self clearing bit */
66 case TAS2770_LiveInterruptReg0:
67 case TAS2770_LiveInterruptReg1:
68 case TAS2770_LatchedInterruptReg0:/* Sticky interrupt flags */
69 case TAS2770_LatchedInterruptReg1:/* Sticky interrupt flags */
70 case TAS2770_VBATMSB:
71 case TAS2770_VBATLSB:
72 case TAS2770_TEMPMSB:
73 case TAS2770_TEMPLSB:
74 return true;
75 }
76 return false;
77 }
79 static bool tas2770_writeable(struct device *dev, unsigned int reg)
80 {
81 switch (reg) {
82 case TAS2770_LiveInterruptReg0:
83 case TAS2770_LiveInterruptReg1:
84 case TAS2770_LatchedInterruptReg0:
85 case TAS2770_LatchedInterruptReg1:
86 case TAS2770_VBATMSB:
87 case TAS2770_VBATLSB:
88 case TAS2770_TEMPMSB:
89 case TAS2770_TEMPLSB:
90 case TAS2770_TDMClockdetectionmonitor:
91 case TAS2770_RevisionandPGID:
92 return false;
93 }
94 return true;
95 }
96 static const struct regmap_config tas2770_i2c_regmap = {
97 .reg_bits = 8,
98 .val_bits = 8,
99 .writeable_reg = tas2770_writeable,
100 .volatile_reg = tas2770_volatile,
101 .reg_defaults = tas2770_reg_defaults,
102 .num_reg_defaults = ARRAY_SIZE(tas2770_reg_defaults),
103 .cache_type = REGCACHE_RBTREE,
104 .max_register = 1 * 128,
105 };
108 static void tas2770_hw_reset(struct tas2770_priv *pTAS2770)
109 {
110 if (gpio_is_valid(pTAS2770->mnResetGPIO)) {
111 gpio_direction_output(pTAS2770->mnResetGPIO, 0);
112 msleep(5);
113 gpio_direction_output(pTAS2770->mnResetGPIO, 1);
114 msleep(2);
115 }
117 pTAS2770->mnCurrentBook = -1;
118 pTAS2770->mnCurrentPage = -1;
119 }
121 void tas2770_enableIRQ(struct tas2770_priv *pTAS2770, bool enable)
122 {
123 if (enable) {
124 if (pTAS2770->mbIRQEnable)
125 return;
127 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
128 enable_irq(pTAS2770->mnIRQ);
130 schedule_delayed_work(&pTAS2770->irq_work, msecs_to_jiffies(10));
131 pTAS2770->mbIRQEnable = true;
132 } else {
133 if (!pTAS2770->mbIRQEnable)
134 return;
136 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
137 disable_irq_nosync(pTAS2770->mnIRQ);
138 pTAS2770->mbIRQEnable = false;
139 }
140 }
142 static void irq_work_routine(struct work_struct *work)
143 {
144 struct tas2770_priv *pTAS2770 =
145 container_of(work, struct tas2770_priv, irq_work.work);
147 #ifdef CONFIG_TAS2770_CODEC
148 mutex_lock(&pTAS2770->codec_lock);
149 #endif
151 if (pTAS2770->mbRuntimeSuspend) {
152 dev_info(pTAS2770->dev, "%s, Runtime Suspended\n", __func__);
153 goto end;
154 }
156 if (!pTAS2770->mbPowerUp) {
157 dev_info(pTAS2770->dev, "%s, device not powered\n", __func__);
158 goto end;
159 }
161 end:
162 #ifdef CONFIG_TAS2770_CODEC
163 mutex_unlock(&pTAS2770->codec_lock);
164 #endif
165 }
167 static enum hrtimer_restart timer_func(struct hrtimer *timer)
168 {
169 struct tas2770_priv *pTAS2770 = container_of(timer,
170 struct tas2770_priv, mtimer);
172 if (pTAS2770->mbPowerUp) {
173 if (!delayed_work_pending(&pTAS2770->irq_work))
174 schedule_delayed_work(&pTAS2770->irq_work,
175 msecs_to_jiffies(20));
176 }
178 return HRTIMER_NORESTART;
179 }
181 static irqreturn_t tas2770_irq_handler(int irq, void *dev_id)
182 {
183 struct tas2770_priv *pTAS2770 = (struct tas2770_priv *)dev_id;
185 tas2770_enableIRQ(pTAS2770, false);
187 /* get IRQ status after 100 ms */
188 if (!delayed_work_pending(&pTAS2770->irq_work))
189 schedule_delayed_work(&pTAS2770->irq_work,
190 msecs_to_jiffies(100));
192 return IRQ_HANDLED;
193 }
195 static int tas2770_runtime_suspend(struct tas2770_priv *pTAS2770)
196 {
197 dev_dbg(pTAS2770->dev, "%s\n", __func__);
199 pTAS2770->mbRuntimeSuspend = true;
201 if (hrtimer_active(&pTAS2770->mtimer)) {
202 dev_dbg(pTAS2770->dev, "cancel die temp timer\n");
203 hrtimer_cancel(&pTAS2770->mtimer);
204 }
206 if (delayed_work_pending(&pTAS2770->irq_work)) {
207 dev_dbg(pTAS2770->dev, "cancel IRQ work\n");
208 cancel_delayed_work_sync(&pTAS2770->irq_work);
209 }
211 return 0;
212 }
214 #define CHECK_PERIOD 5000 /* 5 second */
215 static int tas2770_runtime_resume(struct tas2770_priv *pTAS2770)
216 {
217 dev_dbg(pTAS2770->dev, "%s\n", __func__);
219 if (pTAS2770->mbPowerUp) {
220 if (!hrtimer_active(&pTAS2770->mtimer)) {
221 hrtimer_start(&pTAS2770->mtimer,
222 ns_to_ktime((u64)CHECK_PERIOD * NSEC_PER_MSEC),
223 HRTIMER_MODE_REL);
224 }
226 }
228 pTAS2770->mbRuntimeSuspend = false;
230 return 0;
231 }
233 static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *pTAS2770)
234 {
235 struct device_node *np = dev->of_node;
236 int rc = 0, ret = 0;
238 rc = of_property_read_u32(np, "ti,asi-format", &pTAS2770->mnASIFormat);
239 if (rc) {
240 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
241 "ti,asi-format", np->full_name, rc);
242 } else {
243 dev_dbg(pTAS2770->dev, "ti,asi-format=%d",
244 pTAS2770->mnASIFormat);
245 }
247 pTAS2770->mnResetGPIO = of_get_named_gpio(np, "ti,reset-gpio", 0);
248 if (!gpio_is_valid(pTAS2770->mnResetGPIO)) {
249 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
250 "ti,reset-gpio", np->full_name, pTAS2770->mnResetGPIO);
251 } else {
252 dev_dbg(pTAS2770->dev, "ti,reset-gpio=%d",
253 pTAS2770->mnResetGPIO);
254 }
256 pTAS2770->mnIRQGPIO = of_get_named_gpio(np, "ti,irq-gpio", 0);
257 if (!gpio_is_valid(pTAS2770->mnIRQGPIO)) {
258 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
259 "ti,irq-gpio", np->full_name, pTAS2770->mnIRQGPIO);
260 } else {
261 dev_dbg(pTAS2770->dev, "ti,irq-gpio=%d", pTAS2770->mnIRQGPIO);
262 }
264 of_property_read_u32(np, "ti,left-slot", &pTAS2770->mnLeftSlot);
265 if (rc) {
266 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
267 "ti,left-slot", np->full_name, rc);
268 } else {
269 dev_dbg(pTAS2770->dev, "ti,left-slot=%d",
270 pTAS2770->mnLeftSlot);
271 }
273 of_property_read_u32(np, "ti,right-slot", &pTAS2770->mnRightSlot);
274 if (rc) {
275 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
276 "ti,right-slot", np->full_name, rc);
277 } else {
278 dev_dbg(pTAS2770->dev, "ti,right-slot=%d",
279 pTAS2770->mnRightSlot);
280 }
282 of_property_read_u32(np, "ti,imon-slot-no", &pTAS2770->mnImon_slot_no);
283 if (rc) {
284 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
285 "ti,imon-slot-no", np->full_name, rc);
286 } else {
287 dev_dbg(pTAS2770->dev, "ti,imon-slot-no=%d",
288 pTAS2770->mnImon_slot_no);
289 }
291 of_property_read_u32(np, "ti,vmon-slot-no", &pTAS2770->mnVmon_slot_no);
292 if (rc) {
293 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
294 "ti,vmon-slot-no", np->full_name, rc);
295 } else {
296 dev_dbg(pTAS2770->dev, "ti,vmon-slot-no=%d",
297 pTAS2770->mnVmon_slot_no);
298 }
300 return ret;
301 }
303 static int tas2770_i2c_probe(struct i2c_client *client,
304 const struct i2c_device_id *id)
305 {
306 struct tas2770_priv *pTAS2770;
307 int nResult;
309 dev_info(&client->dev, "%s enter\n", __func__);
311 pTAS2770 = devm_kzalloc(&client->dev,
312 sizeof(struct tas2770_priv), GFP_KERNEL);
313 if (pTAS2770 == NULL) {
314 nResult = -ENOMEM;
315 goto end;
316 }
318 pTAS2770->dev = &client->dev;
319 i2c_set_clientdata(client, pTAS2770);
320 dev_set_drvdata(&client->dev, pTAS2770);
322 pTAS2770->regmap = devm_regmap_init_i2c(client, &tas2770_i2c_regmap);
323 if (IS_ERR(pTAS2770->regmap)) {
324 nResult = PTR_ERR(pTAS2770->regmap);
325 dev_err(&client->dev, "Failed to allocate register map: %d\n",
326 nResult);
327 goto end;
328 }
330 if (client->dev.of_node)
331 tas2770_parse_dt(&client->dev, pTAS2770);
333 if (gpio_is_valid(pTAS2770->mnResetGPIO)) {
334 nResult = gpio_request(pTAS2770->mnResetGPIO, "TAS2770_RESET");
335 if (nResult) {
336 dev_err(pTAS2770->dev, "%s: Failed to request gpio %d\n",
337 __func__, pTAS2770->mnResetGPIO);
338 nResult = -EINVAL;
339 goto free_gpio;
340 }
341 }
343 if (gpio_is_valid(pTAS2770->mnIRQGPIO)) {
344 nResult = gpio_request(pTAS2770->mnIRQGPIO, "TAS2770-IRQ");
345 if (nResult < 0) {
346 dev_err(pTAS2770->dev, "%s: GPIO %d request error\n",
347 __func__, pTAS2770->mnIRQGPIO);
348 goto free_gpio;
349 }
350 gpio_direction_input(pTAS2770->mnIRQGPIO);
351 pTAS2770->mnIRQ = gpio_to_irq(pTAS2770->mnIRQGPIO);
352 dev_dbg(pTAS2770->dev, "irq = %d\n", pTAS2770->mnIRQ);
353 nResult = request_threaded_irq(pTAS2770->mnIRQ,
354 tas2770_irq_handler, NULL,
355 IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
356 client->name, pTAS2770);
357 if (nResult < 0) {
358 dev_err(pTAS2770->dev,
359 "request_irq failed, %d\n", nResult);
360 goto free_gpio;
361 }
362 disable_irq_nosync(pTAS2770->mnIRQ);
363 INIT_DELAYED_WORK(&pTAS2770->irq_work, irq_work_routine);
364 }
365 pTAS2770->mnAddr = client->addr;
366 pTAS2770->adapter = client->adapter;
367 pTAS2770->hw_reset = tas2770_hw_reset;
368 pTAS2770->enableIRQ = tas2770_enableIRQ;
369 pTAS2770->runtime_suspend = tas2770_runtime_suspend;
370 pTAS2770->runtime_resume = tas2770_runtime_resume;
371 pTAS2770->mnCh_size = 0;
372 pTAS2770->mnSlot_width = 0;
374 tas2770_hw_reset(pTAS2770);
376 mutex_init(&pTAS2770->dev_lock);
377 if (nResult < 0)
378 goto destroy_mutex;
380 #ifdef CONFIG_TAS2770_CODEC
381 mutex_init(&pTAS2770->codec_lock);
382 tas2770_register_codec(pTAS2770);
383 #endif
385 hrtimer_init(&pTAS2770->mtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
386 pTAS2770->mtimer.function = timer_func;
388 destroy_mutex:
389 if (nResult < 0)
390 mutex_destroy(&pTAS2770->dev_lock);
392 free_gpio:
393 if (nResult < 0) {
394 if (gpio_is_valid(pTAS2770->mnResetGPIO))
395 gpio_free(pTAS2770->mnResetGPIO);
396 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
397 gpio_free(pTAS2770->mnIRQGPIO);
398 }
400 end:
401 return nResult;
402 }
404 static int tas2770_i2c_remove(struct i2c_client *client)
405 {
406 struct tas2770_priv *pTAS2770 = i2c_get_clientdata(client);
408 dev_info(pTAS2770->dev, "%s\n", __func__);
410 #ifdef CONFIG_TAS2770_CODEC
411 tas2770_deregister_codec(pTAS2770);
412 mutex_destroy(&pTAS2770->codec_lock);
413 #endif
415 if (gpio_is_valid(pTAS2770->mnResetGPIO))
416 gpio_free(pTAS2770->mnResetGPIO);
417 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
418 gpio_free(pTAS2770->mnIRQGPIO);
420 return 0;
421 }
424 static const struct i2c_device_id tas2770_i2c_id[] = {
425 { "tas2770", 0},
426 { }
427 };
428 MODULE_DEVICE_TABLE(i2c, tas2770_i2c_id);
430 #if defined(CONFIG_OF)
431 static const struct of_device_id tas2770_of_match[] = {
432 { .compatible = "ti,tas2770" },
433 {},
434 };
435 MODULE_DEVICE_TABLE(of, tas2770_of_match);
436 #endif
439 static struct i2c_driver tas2770_i2c_driver = {
440 .driver = {
441 .name = "tas2770",
442 .owner = THIS_MODULE,
443 #if defined(CONFIG_OF)
444 .of_match_table = of_match_ptr(tas2770_of_match),
445 #endif
446 },
447 .probe = tas2770_i2c_probe,
448 .remove = tas2770_i2c_remove,
449 .id_table = tas2770_i2c_id,
450 };
452 module_i2c_driver(tas2770_i2c_driver);
454 MODULE_AUTHOR("Texas Instruments Inc.");
455 MODULE_DESCRIPTION("TAS2770 I2C Smart Amplifier driver");
456 MODULE_LICENSE("GPL v2");
457 #endif