9afbbd0cd249909b8ac747ee4ab4f82a70dff7dc
[tas2770sw-android/tas2770sw-android.git] / tas2770-regmap.c
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_BrownOutPreventionReg0:/* has a self clearing bit */
65         case TAS2770_LiveInterruptReg0:
66         case TAS2770_LiveInterruptReg1:
67         case TAS2770_LatchedInterruptReg0:/* Sticky interrupt flags */
68         case TAS2770_LatchedInterruptReg1:/* Sticky interrupt flags */
69         case TAS2770_VBATMSB:
70         case TAS2770_VBATLSB:
71         case TAS2770_TEMPMSB:
72         case TAS2770_TEMPLSB:
73                 return true;
74         }
75         return false;
76 }
78 static bool tas2770_writeable(struct device *dev, unsigned int reg)
79 {
80         switch (reg) {
81         case TAS2770_LiveInterruptReg0:
82         case TAS2770_LiveInterruptReg1:
83         case TAS2770_LatchedInterruptReg0:
84         case TAS2770_LatchedInterruptReg1:
85         case TAS2770_VBATMSB:
86         case TAS2770_VBATLSB:
87         case TAS2770_TEMPMSB:
88         case TAS2770_TEMPLSB:
89         case TAS2770_TDMClockdetectionmonitor:
90         case TAS2770_RevisionandPGID:
91                 return false;
92         }
93         return true;
94 }
95 static const struct regmap_config tas2770_i2c_regmap = {
96         .reg_bits = 8,
97         .val_bits = 8,
98         .writeable_reg = tas2770_writeable,
99         .volatile_reg = tas2770_volatile,
100         .reg_defaults = tas2770_reg_defaults,
101         .num_reg_defaults = ARRAY_SIZE(tas2770_reg_defaults),
102         .cache_type = REGCACHE_RBTREE,
103         .max_register = 1 * 128,
104 };
107 static void tas2770_hw_reset(struct tas2770_priv *pTAS2770)
109         if (gpio_is_valid(pTAS2770->mnResetGPIO)) {
110                 gpio_direction_output(pTAS2770->mnResetGPIO, 0);
111                 msleep(5);
112                 gpio_direction_output(pTAS2770->mnResetGPIO, 1);
113                 msleep(2);
114         }
116         pTAS2770->mnCurrentBook = -1;
117         pTAS2770->mnCurrentPage = -1;
120 void tas2770_enableIRQ(struct tas2770_priv *pTAS2770, bool enable)
122         if (enable) {
123                 if (pTAS2770->mbIRQEnable)
124                         return;
126                 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
127                         enable_irq(pTAS2770->mnIRQ);
129                 schedule_delayed_work(&pTAS2770->irq_work, msecs_to_jiffies(10));
130                 pTAS2770->mbIRQEnable = true;
131         } else {
132                 if (!pTAS2770->mbIRQEnable)
133                         return;
135                 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
136                         disable_irq_nosync(pTAS2770->mnIRQ);
137                 pTAS2770->mbIRQEnable = false;
138         }
141 static void irq_work_routine(struct work_struct *work)
143         struct tas2770_priv *pTAS2770 =
144                 container_of(work, struct tas2770_priv, irq_work.work);
146 #ifdef CONFIG_TAS2770_CODEC
147         mutex_lock(&pTAS2770->codec_lock);
148 #endif
150         if (pTAS2770->mbRuntimeSuspend) {
151                 dev_info(pTAS2770->dev, "%s, Runtime Suspended\n", __func__);
152                 goto end;
153         }
155         if (!pTAS2770->mbPowerUp) {
156                 dev_info(pTAS2770->dev, "%s, device not powered\n", __func__);
157                 goto end;
158         }
160 end:
161 #ifdef CONFIG_TAS2770_CODEC
162         mutex_unlock(&pTAS2770->codec_lock);
163 #endif
166 static enum hrtimer_restart timer_func(struct hrtimer *timer)
168         struct tas2770_priv *pTAS2770 = container_of(timer,
169                 struct tas2770_priv, mtimer);
171         if (pTAS2770->mbPowerUp) {
172                 if (!delayed_work_pending(&pTAS2770->irq_work))
173                         schedule_delayed_work(&pTAS2770->irq_work,
174                                 msecs_to_jiffies(20));
175         }
177         return HRTIMER_NORESTART;
180 static irqreturn_t tas2770_irq_handler(int irq, void *dev_id)
182         struct tas2770_priv *pTAS2770 = (struct tas2770_priv *)dev_id;
184         tas2770_enableIRQ(pTAS2770, false);
186         /* get IRQ status after 100 ms */
187         if (!delayed_work_pending(&pTAS2770->irq_work))
188                 schedule_delayed_work(&pTAS2770->irq_work,
189                         msecs_to_jiffies(100));
191         return IRQ_HANDLED;
194 static int tas2770_runtime_suspend(struct tas2770_priv *pTAS2770)
196         dev_dbg(pTAS2770->dev, "%s\n", __func__);
198         pTAS2770->mbRuntimeSuspend = true;
200         if (hrtimer_active(&pTAS2770->mtimer)) {
201                 dev_dbg(pTAS2770->dev, "cancel die temp timer\n");
202                 hrtimer_cancel(&pTAS2770->mtimer);
203         }
205         if (delayed_work_pending(&pTAS2770->irq_work)) {
206                 dev_dbg(pTAS2770->dev, "cancel IRQ work\n");
207                 cancel_delayed_work_sync(&pTAS2770->irq_work);
208         }
210         return 0;
213 #define CHECK_PERIOD    5000    /* 5 second */
214 static int tas2770_runtime_resume(struct tas2770_priv *pTAS2770)
216         dev_dbg(pTAS2770->dev, "%s\n", __func__);
218         if (pTAS2770->mbPowerUp) {
219                 if (!hrtimer_active(&pTAS2770->mtimer)) {
220                         hrtimer_start(&pTAS2770->mtimer,
221                                 ns_to_ktime((u64)CHECK_PERIOD * NSEC_PER_MSEC),
222                                 HRTIMER_MODE_REL);
223                 }
225         }
227         pTAS2770->mbRuntimeSuspend = false;
229         return 0;
232 static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *pTAS2770)
234         struct device_node *np = dev->of_node;
235         int rc = 0, ret = 0;
237         rc = of_property_read_u32(np, "ti,asi-format", &pTAS2770->mnASIFormat);
238         if (rc) {
239                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
240                         "ti,asi-format", np->full_name, rc);
241         } else {
242                 dev_dbg(pTAS2770->dev, "ti,asi-format=%d",
243                         pTAS2770->mnASIFormat);
244         }
246         pTAS2770->mnResetGPIO = of_get_named_gpio(np, "ti,reset-gpio", 0);
247         if (!gpio_is_valid(pTAS2770->mnResetGPIO)) {
248                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
249                         "ti,reset-gpio", np->full_name, pTAS2770->mnResetGPIO);
250         } else {
251                 dev_dbg(pTAS2770->dev, "ti,reset-gpio=%d",
252                         pTAS2770->mnResetGPIO);
253         }
255         pTAS2770->mnIRQGPIO = of_get_named_gpio(np, "ti,irq-gpio", 0);
256         if (!gpio_is_valid(pTAS2770->mnIRQGPIO)) {
257                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
258                         "ti,irq-gpio", np->full_name, pTAS2770->mnIRQGPIO);
259         } else {
260                 dev_dbg(pTAS2770->dev, "ti,irq-gpio=%d", pTAS2770->mnIRQGPIO);
261         }
263         of_property_read_u32(np, "ti,left-slot", &pTAS2770->mnLeftSlot);
264         if (rc) {
265                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
266                         "ti,left-slot", np->full_name, rc);
267         } else {
268                 dev_dbg(pTAS2770->dev, "ti,left-slot=%d",
269                         pTAS2770->mnLeftSlot);
270         }
272         of_property_read_u32(np, "ti,right-slot", &pTAS2770->mnRightSlot);
273         if (rc) {
274                 dev_err(pTAS2770->dev, "Looking up %s property in node %s failed %d\n",
275                         "ti,right-slot", np->full_name, rc);
276         } else {
277                 dev_dbg(pTAS2770->dev, "ti,right-slot=%d",
278                         pTAS2770->mnRightSlot);
279         }
281         return ret;
284 static int tas2770_i2c_probe(struct i2c_client *client,
285                         const struct i2c_device_id *id)
287         struct tas2770_priv *pTAS2770;
288         int nResult;
290         dev_info(&client->dev, "%s enter\n", __func__);
292         pTAS2770 = devm_kzalloc(&client->dev,
293                 sizeof(struct tas2770_priv), GFP_KERNEL);
294         if (pTAS2770 == NULL) {
295                 nResult = -ENOMEM;
296                 goto end;
297         }
299         pTAS2770->dev = &client->dev;
300         i2c_set_clientdata(client, pTAS2770);
301         dev_set_drvdata(&client->dev, pTAS2770);
303         pTAS2770->regmap = devm_regmap_init_i2c(client, &tas2770_i2c_regmap);
304         if (IS_ERR(pTAS2770->regmap)) {
305                 nResult = PTR_ERR(pTAS2770->regmap);
306                 dev_err(&client->dev, "Failed to allocate register map: %d\n",
307                                         nResult);
308                 goto end;
309         }
311         if (client->dev.of_node)
312                 tas2770_parse_dt(&client->dev, pTAS2770);
314         if (gpio_is_valid(pTAS2770->mnResetGPIO)) {
315                 nResult = gpio_request(pTAS2770->mnResetGPIO, "TAS2770_RESET");
316                 if (nResult) {
317                         dev_err(pTAS2770->dev, "%s: Failed to request gpio %d\n",
318                                 __func__, pTAS2770->mnResetGPIO);
319                         nResult = -EINVAL;
320                         goto free_gpio;
321                 }
322         }
324         if (gpio_is_valid(pTAS2770->mnIRQGPIO)) {
325                 nResult = gpio_request(pTAS2770->mnIRQGPIO, "TAS2770-IRQ");
326                 if (nResult < 0) {
327                         dev_err(pTAS2770->dev, "%s: GPIO %d request error\n",
328                                 __func__, pTAS2770->mnIRQGPIO);
329                         goto free_gpio;
330                 }
331                 gpio_direction_input(pTAS2770->mnIRQGPIO);
332                 pTAS2770->mnIRQ = gpio_to_irq(pTAS2770->mnIRQGPIO);
333                 dev_dbg(pTAS2770->dev, "irq = %d\n", pTAS2770->mnIRQ);
334                 nResult = request_threaded_irq(pTAS2770->mnIRQ,
335                                         tas2770_irq_handler, NULL,
336                                         IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
337                                         client->name, pTAS2770);
338                 if (nResult < 0) {
339                         dev_err(pTAS2770->dev,
340                                 "request_irq failed, %d\n", nResult);
341                         goto free_gpio;
342                 }
343                 disable_irq_nosync(pTAS2770->mnIRQ);
344                 INIT_DELAYED_WORK(&pTAS2770->irq_work, irq_work_routine);
345         }
347         pTAS2770->hw_reset = tas2770_hw_reset;
348         pTAS2770->enableIRQ = tas2770_enableIRQ;
349         pTAS2770->runtime_suspend = tas2770_runtime_suspend;
350         pTAS2770->runtime_resume = tas2770_runtime_resume;
351         mutex_init(&pTAS2770->dev_lock);
352         if (nResult < 0)
353                 goto destroy_mutex;
355 #ifdef CONFIG_TAS2770_CODEC
356         mutex_init(&pTAS2770->codec_lock);
357         tas2770_register_codec(pTAS2770);
358 #endif
360         hrtimer_init(&pTAS2770->mtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
361         pTAS2770->mtimer.function = timer_func;
363 destroy_mutex:
364         if (nResult < 0)
365                 mutex_destroy(&pTAS2770->dev_lock);
367 free_gpio:
368         if (nResult < 0) {
369                 if (gpio_is_valid(pTAS2770->mnResetGPIO))
370                         gpio_free(pTAS2770->mnResetGPIO);
371                 if (gpio_is_valid(pTAS2770->mnIRQGPIO))
372                         gpio_free(pTAS2770->mnIRQGPIO);
373         }
375 end:
376         return nResult;
379 static int tas2770_i2c_remove(struct i2c_client *client)
381         struct tas2770_priv *pTAS2770 = i2c_get_clientdata(client);
383         dev_info(pTAS2770->dev, "%s\n", __func__);
385 #ifdef CONFIG_TAS2770_CODEC
386         tas2770_deregister_codec(pTAS2770);
387         mutex_destroy(&pTAS2770->codec_lock);
388 #endif
390         if (gpio_is_valid(pTAS2770->mnResetGPIO))
391                 gpio_free(pTAS2770->mnResetGPIO);
392         if (gpio_is_valid(pTAS2770->mnIRQGPIO))
393                 gpio_free(pTAS2770->mnIRQGPIO);
395         return 0;
399 static const struct i2c_device_id tas2770_i2c_id[] = {
400         { "tas2770", 0},
401         { }
402 };
403 MODULE_DEVICE_TABLE(i2c, tas2770_i2c_id);
405 #if defined(CONFIG_OF)
406 static const struct of_device_id tas2770_of_match[] = {
407         { .compatible = "ti,tas2770" },
408         {},
409 };
410 MODULE_DEVICE_TABLE(of, tas2770_of_match);
411 #endif
414 static struct i2c_driver tas2770_i2c_driver = {
415         .driver = {
416                 .name   = "tas2770",
417                 .owner  = THIS_MODULE,
418 #if defined(CONFIG_OF)
419                 .of_match_table = of_match_ptr(tas2770_of_match),
420 #endif
421         },
422         .probe      = tas2770_i2c_probe,
423         .remove     = tas2770_i2c_remove,
424         .id_table   = tas2770_i2c_id,
425 };
427 module_i2c_driver(tas2770_i2c_driver);
429 MODULE_AUTHOR("Texas Instruments Inc.");
430 MODULE_DESCRIPTION("TAS2770 I2C Smart Amplifier driver");
431 MODULE_LICENSE("GPL v2");
432 #endif