blob: bbb2509f835b3b9b425c6ec325e29a669c4ab9de [file] [log] [blame]
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/kernel.h>
14#include <linux/module.h>
15#include <linux/slab.h>
16#include <linux/mfd/core.h>
17#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
18#include <linux/mfd/wcd9xxx/core.h>
19#include <linux/mfd/wcd9xxx/pdata.h>
20#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
21
22#include <linux/delay.h>
23#include <linux/gpio.h>
24#include <linux/debugfs.h>
25#include <linux/regulator/consumer.h>
26#include <linux/i2c.h>
27#include <sound/soc.h>
28
29#define WCD9XXX_SLIM_GLA_MAX_RETRIES 5
30#define WCD9XXX_REGISTER_START_OFFSET 0x800
31#define WCD9XXX_SLIM_RW_MAX_TRIES 3
32
33#define MAX_WCD9XXX_DEVICE 4
34#define WCD9XXX_I2C_MODE 0x03
35
36struct wcd9xxx_i2c {
37 struct i2c_client *client;
38 struct i2c_msg xfer_msg[2];
39 struct mutex xfer_lock;
40 int mod_id;
41};
42
43struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -070044static int wcd9xxx_intf = -1;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053045
46static int wcd9xxx_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
47 int bytes, void *dest, bool interface_reg)
48{
49 int ret;
50 u8 *buf = dest;
51
52 if (bytes <= 0) {
53 dev_err(wcd9xxx->dev, "Invalid byte read length %d\n", bytes);
54 return -EINVAL;
55 }
56
57 ret = wcd9xxx->read_dev(wcd9xxx, reg, bytes, dest, interface_reg);
58 if (ret < 0) {
59 dev_err(wcd9xxx->dev, "Codec read failed\n");
60 return ret;
61 } else
Kiran Kandi1e6371d2012-03-29 11:48:57 -070062 dev_dbg(wcd9xxx->dev, "Read 0x%02x from 0x%x\n",
63 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053064
65 return 0;
66}
67int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
68{
69 u8 val;
70 int ret;
71
72 mutex_lock(&wcd9xxx->io_lock);
73 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, false);
74 mutex_unlock(&wcd9xxx->io_lock);
75
76 if (ret < 0)
77 return ret;
78 else
79 return val;
80}
81EXPORT_SYMBOL_GPL(wcd9xxx_reg_read);
82
83static int wcd9xxx_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
84 int bytes, void *src, bool interface_reg)
85{
86 u8 *buf = src;
87
88 if (bytes <= 0) {
89 pr_err("%s: Error, invalid write length\n", __func__);
90 return -EINVAL;
91 }
92
Kiran Kandi1e6371d2012-03-29 11:48:57 -070093 dev_dbg(wcd9xxx->dev, "Write %02x to 0x%x\n",
94 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053095
96 return wcd9xxx->write_dev(wcd9xxx, reg, bytes, src, interface_reg);
97}
98
99int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
100 u8 val)
101{
102 int ret;
103
104 mutex_lock(&wcd9xxx->io_lock);
105 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, false);
106 mutex_unlock(&wcd9xxx->io_lock);
107
108 return ret;
109}
110EXPORT_SYMBOL_GPL(wcd9xxx_reg_write);
111
112static u8 wcd9xxx_pgd_la;
113static u8 wcd9xxx_inf_la;
114
115int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
116{
117 u8 val;
118 int ret;
119
120 mutex_lock(&wcd9xxx->io_lock);
121 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, true);
122 mutex_unlock(&wcd9xxx->io_lock);
123
124 if (ret < 0)
125 return ret;
126 else
127 return val;
128}
129EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_read);
130
131int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
132 u8 val)
133{
134 int ret;
135
136 mutex_lock(&wcd9xxx->io_lock);
137 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, true);
138 mutex_unlock(&wcd9xxx->io_lock);
139
140 return ret;
141}
142EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_write);
143
144int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
145 int count, u8 *buf)
146{
147 int ret;
148
149 mutex_lock(&wcd9xxx->io_lock);
150
151 ret = wcd9xxx_read(wcd9xxx, reg, count, buf, false);
152
153 mutex_unlock(&wcd9xxx->io_lock);
154
155 return ret;
156}
157EXPORT_SYMBOL_GPL(wcd9xxx_bulk_read);
158
159int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
160 int count, u8 *buf)
161{
162 int ret;
163
164 mutex_lock(&wcd9xxx->io_lock);
165
166 ret = wcd9xxx_write(wcd9xxx, reg, count, buf, false);
167
168 mutex_unlock(&wcd9xxx->io_lock);
169
170 return ret;
171}
172EXPORT_SYMBOL_GPL(wcd9xxx_bulk_write);
173
174static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg,
175 int bytes, void *dest, bool interface)
176{
177 int ret;
178 struct slim_ele_access msg;
179 int slim_read_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
180 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
181 msg.num_bytes = bytes;
182 msg.comp = NULL;
183
184 while (1) {
185 mutex_lock(&wcd9xxx->xfer_lock);
186 ret = slim_request_val_element(interface ?
187 wcd9xxx->slim_slave : wcd9xxx->slim,
188 &msg, dest, bytes);
189 mutex_unlock(&wcd9xxx->xfer_lock);
190 if (likely(ret == 0) || (--slim_read_tries == 0))
191 break;
192 usleep_range(5000, 5000);
193 }
194
195 if (ret)
196 pr_err("%s: Error, Codec read failed (%d)\n", __func__, ret);
197
198 return ret;
199}
200/* Interface specifies whether the write is to the interface or general
201 * registers.
202 */
203static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx,
204 unsigned short reg, int bytes, void *src, bool interface)
205{
206 int ret;
207 struct slim_ele_access msg;
208 int slim_write_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
209 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
210 msg.num_bytes = bytes;
211 msg.comp = NULL;
212
213 while (1) {
214 mutex_lock(&wcd9xxx->xfer_lock);
215 ret = slim_change_val_element(interface ?
216 wcd9xxx->slim_slave : wcd9xxx->slim,
217 &msg, src, bytes);
218 mutex_unlock(&wcd9xxx->xfer_lock);
219 if (likely(ret == 0) || (--slim_write_tries == 0))
220 break;
221 usleep_range(5000, 5000);
222 }
223
224 if (ret)
225 pr_err("%s: Error, Codec write failed (%d)\n", __func__, ret);
226
227 return ret;
228}
229
230static struct mfd_cell tabla1x_devs[] = {
231 {
232 .name = "tabla1x_codec",
233 },
234};
235
236static struct mfd_cell tabla_devs[] = {
237 {
238 .name = "tabla_codec",
239 },
240};
241
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530242static struct mfd_cell sitar_devs[] = {
243 {
244 .name = "sitar_codec",
245 },
246};
247
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530248static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
249{
250 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x4);
251 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 0);
252 usleep_range(5000, 5000);
253 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 3);
254 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 3);
255}
256
257static void wcd9xxx_bring_down(struct wcd9xxx *wcd9xxx)
258{
259 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x7);
260 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x6);
261 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0xe);
262 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x8);
263}
264
265static int wcd9xxx_reset(struct wcd9xxx *wcd9xxx)
266{
267 int ret;
268
269 if (wcd9xxx->reset_gpio) {
270 ret = gpio_request(wcd9xxx->reset_gpio, "CDC_RESET");
271 if (ret) {
272 pr_err("%s: Failed to request gpio %d\n", __func__,
273 wcd9xxx->reset_gpio);
274 wcd9xxx->reset_gpio = 0;
275 return ret;
276 }
277
278 gpio_direction_output(wcd9xxx->reset_gpio, 1);
279 msleep(20);
280 gpio_direction_output(wcd9xxx->reset_gpio, 0);
281 msleep(20);
282 gpio_direction_output(wcd9xxx->reset_gpio, 1);
283 msleep(20);
284 }
285 return 0;
286}
287
288static void wcd9xxx_free_reset(struct wcd9xxx *wcd9xxx)
289{
290 if (wcd9xxx->reset_gpio) {
291 gpio_free(wcd9xxx->reset_gpio);
292 wcd9xxx->reset_gpio = 0;
293 }
294}
295
296static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx, int irq)
297{
298 int ret;
299 u8 idbyte_0, idbyte_1, idbyte_2, idbyte_3;
300 struct mfd_cell *wcd9xxx_dev = NULL;
301 int wcd9xxx_dev_size = 0;
302
303 mutex_init(&wcd9xxx->io_lock);
304 mutex_init(&wcd9xxx->xfer_lock);
305
306 mutex_init(&wcd9xxx->pm_lock);
307 wcd9xxx->wlock_holders = 0;
308 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
309 init_waitqueue_head(&wcd9xxx->pm_wq);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700310 pm_qos_add_request(&wcd9xxx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
311 PM_QOS_DEFAULT_VALUE);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530312
313 dev_set_drvdata(wcd9xxx->dev, wcd9xxx);
314
315 wcd9xxx_bring_up(wcd9xxx);
316
317 ret = wcd9xxx_irq_init(wcd9xxx);
318 if (ret) {
319 pr_err("IRQ initialization failed\n");
320 goto err;
321 }
322
323 idbyte_0 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_0);
324 idbyte_1 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_1);
325 idbyte_2 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_2);
326 idbyte_3 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_3);
327
328 wcd9xxx->version = wcd9xxx_reg_read(wcd9xxx,
329 WCD9XXX_A_CHIP_VERSION) & 0x1F;
330 pr_info("%s : Codec version %u initialized\n",
331 __func__, wcd9xxx->version);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530332 pr_info("idbyte_0[%08x] idbyte_1[%08x] idbyte_2[%08x] idbyte_3[%08x]\n",
333 idbyte_0, idbyte_1, idbyte_2, idbyte_3);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530334
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700335 if (wcd9xxx->slim != NULL) {
336 if (!strncmp(wcd9xxx->slim->name, "tabla", 5)) {
337 if (TABLA_IS_1_X(wcd9xxx->version)) {
338 wcd9xxx_dev = tabla1x_devs;
339 wcd9xxx_dev_size = ARRAY_SIZE(tabla1x_devs);
340 } else {
341 wcd9xxx_dev = tabla_devs;
342 wcd9xxx_dev_size = ARRAY_SIZE(tabla_devs);
343 }
344 } else {
345 wcd9xxx_dev = sitar_devs;
346 wcd9xxx_dev_size = ARRAY_SIZE(sitar_devs);
347 }
348 } else {
349 /* Need to add here check for Tabla.
350 * For now the read of version takes
351 * care of now only tabla.
352 */
353 pr_debug("%s : Read codec version using I2C\n", __func__);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530354 if (TABLA_IS_1_X(wcd9xxx->version)) {
355 wcd9xxx_dev = tabla1x_devs;
356 wcd9xxx_dev_size = ARRAY_SIZE(tabla1x_devs);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700357 } else if (TABLA_IS_2_0(wcd9xxx->version)) {
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530358 wcd9xxx_dev = tabla_devs;
359 wcd9xxx_dev_size = ARRAY_SIZE(tabla_devs);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700360 } else {
361 wcd9xxx_dev = sitar_devs;
362 wcd9xxx_dev_size = ARRAY_SIZE(sitar_devs);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530363 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530364 }
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530365
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530366 ret = mfd_add_devices(wcd9xxx->dev, -1,
367 wcd9xxx_dev, wcd9xxx_dev_size,
368 NULL, 0);
369 if (ret != 0) {
370 dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret);
371 goto err_irq;
372 }
373 return ret;
374err_irq:
375 wcd9xxx_irq_exit(wcd9xxx);
376err:
377 wcd9xxx_bring_down(wcd9xxx);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700378 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530379 mutex_destroy(&wcd9xxx->pm_lock);
380 mutex_destroy(&wcd9xxx->io_lock);
381 mutex_destroy(&wcd9xxx->xfer_lock);
382 return ret;
383}
384
385static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx)
386{
387 wcd9xxx_irq_exit(wcd9xxx);
388 wcd9xxx_bring_down(wcd9xxx);
389 wcd9xxx_free_reset(wcd9xxx);
390 mutex_destroy(&wcd9xxx->pm_lock);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700391 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530392 mutex_destroy(&wcd9xxx->io_lock);
393 mutex_destroy(&wcd9xxx->xfer_lock);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700394 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
395 slim_remove_device(wcd9xxx->slim_slave);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530396 kfree(wcd9xxx);
397}
398
399
400#ifdef CONFIG_DEBUG_FS
401struct wcd9xxx *debugCodec;
402
403static struct dentry *debugfs_wcd9xxx_dent;
404static struct dentry *debugfs_peek;
405static struct dentry *debugfs_poke;
406
407static unsigned char read_data;
408
409static int codec_debug_open(struct inode *inode, struct file *file)
410{
411 file->private_data = inode->i_private;
412 return 0;
413}
414
415static int get_parameters(char *buf, long int *param1, int num_of_par)
416{
417 char *token;
418 int base, cnt;
419
420 token = strsep(&buf, " ");
421
422 for (cnt = 0; cnt < num_of_par; cnt++) {
423 if (token != NULL) {
424 if ((token[1] == 'x') || (token[1] == 'X'))
425 base = 16;
426 else
427 base = 10;
428
429 if (strict_strtoul(token, base, &param1[cnt]) != 0)
430 return -EINVAL;
431
432 token = strsep(&buf, " ");
433 } else
434 return -EINVAL;
435 }
436 return 0;
437}
438
439static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
440 size_t count, loff_t *ppos)
441{
442 char lbuf[8];
443
444 snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
445 return simple_read_from_buffer(ubuf, count, ppos, lbuf,
446 strnlen(lbuf, 7));
447}
448
449
450static ssize_t codec_debug_write(struct file *filp,
451 const char __user *ubuf, size_t cnt, loff_t *ppos)
452{
453 char *access_str = filp->private_data;
454 char lbuf[32];
455 int rc;
456 long int param[5];
457
458 if (cnt > sizeof(lbuf) - 1)
459 return -EINVAL;
460
461 rc = copy_from_user(lbuf, ubuf, cnt);
462 if (rc)
463 return -EFAULT;
464
465 lbuf[cnt] = '\0';
466
467 if (!strncmp(access_str, "poke", 6)) {
468 /* write */
469 rc = get_parameters(lbuf, param, 2);
470 if ((param[0] <= 0x3FF) && (param[1] <= 0xFF) &&
471 (rc == 0))
472 wcd9xxx_interface_reg_write(debugCodec, param[0],
473 param[1]);
474 else
475 rc = -EINVAL;
476 } else if (!strncmp(access_str, "peek", 6)) {
477 /* read */
478 rc = get_parameters(lbuf, param, 1);
479 if ((param[0] <= 0x3FF) && (rc == 0))
480 read_data = wcd9xxx_interface_reg_read(debugCodec,
481 param[0]);
482 else
483 rc = -EINVAL;
484 }
485
486 if (rc == 0)
487 rc = cnt;
488 else
489 pr_err("%s: rc = %d\n", __func__, rc);
490
491 return rc;
492}
493
494static const struct file_operations codec_debug_ops = {
495 .open = codec_debug_open,
496 .write = codec_debug_write,
497 .read = codec_debug_read
498};
499#endif
500
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700501static int wcd9xxx_enable_supplies(struct wcd9xxx *wcd9xxx,
502 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530503{
504 int ret;
505 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530506 wcd9xxx->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
507 ARRAY_SIZE(pdata->regulator),
508 GFP_KERNEL);
509 if (!wcd9xxx->supplies) {
510 ret = -ENOMEM;
511 goto err;
512 }
513
514 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++)
515 wcd9xxx->supplies[i].supply = pdata->regulator[i].name;
516
517 ret = regulator_bulk_get(wcd9xxx->dev, ARRAY_SIZE(pdata->regulator),
518 wcd9xxx->supplies);
519 if (ret != 0) {
520 dev_err(wcd9xxx->dev, "Failed to get supplies: err = %d\n",
521 ret);
522 goto err_supplies;
523 }
524
525 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
526 ret = regulator_set_voltage(wcd9xxx->supplies[i].consumer,
527 pdata->regulator[i].min_uV, pdata->regulator[i].max_uV);
528 if (ret) {
529 pr_err("%s: Setting regulator voltage failed for "
530 "regulator %s err = %d\n", __func__,
531 wcd9xxx->supplies[i].supply, ret);
532 goto err_get;
533 }
534
535 ret = regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer,
536 pdata->regulator[i].optimum_uA);
537 if (ret < 0) {
538 pr_err("%s: Setting regulator optimum mode failed for "
539 "regulator %s err = %d\n", __func__,
540 wcd9xxx->supplies[i].supply, ret);
541 goto err_get;
542 }
543 }
544
545 ret = regulator_bulk_enable(ARRAY_SIZE(pdata->regulator),
546 wcd9xxx->supplies);
547 if (ret != 0) {
548 dev_err(wcd9xxx->dev, "Failed to enable supplies: err = %d\n",
549 ret);
550 goto err_configure;
551 }
552 return ret;
553
554err_configure:
555 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
556 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
557 pdata->regulator[i].max_uV);
558 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
559 }
560err_get:
561 regulator_bulk_free(ARRAY_SIZE(pdata->regulator), wcd9xxx->supplies);
562err_supplies:
563 kfree(wcd9xxx->supplies);
564err:
565 return ret;
566}
567
Venkat Sudhir49203862012-05-21 14:29:13 -0700568static void wcd9xxx_disable_supplies(struct wcd9xxx *wcd9xxx,
569 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530570{
571 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530572
573 regulator_bulk_disable(ARRAY_SIZE(pdata->regulator),
574 wcd9xxx->supplies);
575 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
576 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
577 pdata->regulator[i].max_uV);
578 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
579 }
580 regulator_bulk_free(ARRAY_SIZE(pdata->regulator), wcd9xxx->supplies);
581 kfree(wcd9xxx->supplies);
582}
583
584int wcd9xxx_get_intf_type(void)
585{
586 return wcd9xxx_intf;
587}
588EXPORT_SYMBOL_GPL(wcd9xxx_get_intf_type);
589
590struct wcd9xxx_i2c *get_i2c_wcd9xxx_device_info(u16 reg)
591{
592 u16 mask = 0x0f00;
593 int value = 0;
594 struct wcd9xxx_i2c *wcd9xxx = NULL;
595 value = ((reg & mask) >> 8) & 0x000f;
596 switch (value) {
597 case 0:
598 wcd9xxx = &wcd9xxx_modules[0];
599 break;
600 case 1:
601 wcd9xxx = &wcd9xxx_modules[1];
602 break;
603 case 2:
604 wcd9xxx = &wcd9xxx_modules[2];
605 break;
606 case 3:
607 wcd9xxx = &wcd9xxx_modules[3];
608 break;
609 default:
610 break;
611 }
612 return wcd9xxx;
613}
614
615int wcd9xxx_i2c_write_device(u16 reg, u8 *value,
616 u32 bytes)
617{
618
619 struct i2c_msg *msg;
620 int ret = 0;
621 u8 reg_addr = 0;
622 u8 data[bytes + 1];
623 struct wcd9xxx_i2c *wcd9xxx;
624
625 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
626 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
627 pr_err("failed to get device info\n");
628 return -ENODEV;
629 }
630 reg_addr = (u8)reg;
631 msg = &wcd9xxx->xfer_msg[0];
632 msg->addr = wcd9xxx->client->addr;
633 msg->len = bytes + 1;
634 msg->flags = 0;
635 data[0] = reg;
636 data[1] = *value;
637 msg->buf = data;
638 ret = i2c_transfer(wcd9xxx->client->adapter, wcd9xxx->xfer_msg, 1);
639 /* Try again if the write fails */
640 if (ret != 1) {
641 ret = i2c_transfer(wcd9xxx->client->adapter,
642 wcd9xxx->xfer_msg, 1);
643 if (ret != 1) {
644 pr_err("failed to write the device\n");
645 return ret;
646 }
647 }
648 pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
649 return 0;
650}
651
652
653int wcd9xxx_i2c_read_device(unsigned short reg,
654 int bytes, unsigned char *dest)
655{
656 struct i2c_msg *msg;
657 int ret = 0;
658 u8 reg_addr = 0;
659 struct wcd9xxx_i2c *wcd9xxx;
660 u8 i = 0;
661
662 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
663 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
664 pr_err("failed to get device info\n");
665 return -ENODEV;
666 }
667 for (i = 0; i < bytes; i++) {
668 reg_addr = (u8)reg++;
669 msg = &wcd9xxx->xfer_msg[0];
670 msg->addr = wcd9xxx->client->addr;
671 msg->len = 1;
672 msg->flags = 0;
673 msg->buf = &reg_addr;
674
675 msg = &wcd9xxx->xfer_msg[1];
676 msg->addr = wcd9xxx->client->addr;
677 msg->len = 1;
678 msg->flags = I2C_M_RD;
679 msg->buf = dest++;
680 ret = i2c_transfer(wcd9xxx->client->adapter,
681 wcd9xxx->xfer_msg, 2);
682
683 /* Try again if read fails first time */
684 if (ret != 2) {
685 ret = i2c_transfer(wcd9xxx->client->adapter,
686 wcd9xxx->xfer_msg, 2);
687 if (ret != 2) {
688 pr_err("failed to read wcd9xxx register\n");
689 return ret;
690 }
691 }
692 }
693 return 0;
694}
695
696int wcd9xxx_i2c_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
697 int bytes, void *dest, bool interface_reg)
698{
699 return wcd9xxx_i2c_read_device(reg, bytes, dest);
700}
701
702int wcd9xxx_i2c_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
703 int bytes, void *src, bool interface_reg)
704{
705 return wcd9xxx_i2c_write_device(reg, src, bytes);
706}
707
708static int __devinit wcd9xxx_i2c_probe(struct i2c_client *client,
709 const struct i2c_device_id *id)
710{
711 struct wcd9xxx *wcd9xxx;
712 struct wcd9xxx_pdata *pdata = client->dev.platform_data;
713 int val = 0;
714 int ret = 0;
715 static int device_id;
716
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700717 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
718 pr_info("tabla card is already detected in slimbus mode\n");
719 return -ENODEV;
720 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530721 if (device_id > 0) {
722 wcd9xxx_modules[device_id++].client = client;
723 pr_info("probe for other slaves devices of tabla\n");
724 return ret;
725 }
726
727 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
728 if (wcd9xxx == NULL) {
729 pr_err("%s: error, allocation failed\n", __func__);
730 ret = -ENOMEM;
731 goto fail;
732 }
733
734 if (!pdata) {
735 dev_dbg(&client->dev, "no platform data?\n");
736 ret = -EINVAL;
737 goto fail;
738 }
739 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
740 dev_dbg(&client->dev, "can't talk I2C?\n");
741 ret = -EIO;
742 goto fail;
743 }
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530744 dev_set_drvdata(&client->dev, wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530745 wcd9xxx->dev = &client->dev;
746 wcd9xxx->reset_gpio = pdata->reset_gpio;
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700747 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530748 if (ret) {
749 pr_err("%s: Fail to enable Codec supplies\n", __func__);
750 goto err_codec;
751 }
752
753 usleep_range(5, 5);
754 ret = wcd9xxx_reset(wcd9xxx);
755 if (ret) {
756 pr_err("%s: Resetting Codec failed\n", __func__);
757 goto err_supplies;
758 }
759 wcd9xxx_modules[device_id++].client = client;
760
761 wcd9xxx->read_dev = wcd9xxx_i2c_read;
762 wcd9xxx->write_dev = wcd9xxx_i2c_write;
763 wcd9xxx->irq = pdata->irq;
764 wcd9xxx->irq_base = pdata->irq_base;
765
766 /*read the tabla status before initializing the device type*/
767 ret = wcd9xxx_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, &val, 0);
768 if ((ret < 0) || (val != WCD9XXX_I2C_MODE)) {
769 pr_err("failed to read the wcd9xxx status\n");
770 goto err_device_init;
771 }
772
773 ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
774 if (ret) {
775 pr_err("%s: error, initializing device failed\n", __func__);
776 goto err_device_init;
777 }
778 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_I2C;
779
780 return ret;
781err_device_init:
782 wcd9xxx_free_reset(wcd9xxx);
783err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -0700784 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530785err_codec:
786 kfree(wcd9xxx);
787fail:
788 return ret;
789}
790
791static int __devexit wcd9xxx_i2c_remove(struct i2c_client *client)
792{
793 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -0700794 struct wcd9xxx_pdata *pdata = client->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530795 pr_debug("exit\n");
796 wcd9xxx = dev_get_drvdata(&client->dev);
Venkat Sudhir49203862012-05-21 14:29:13 -0700797 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530798 wcd9xxx_device_exit(wcd9xxx);
799 return 0;
800}
801
802static int wcd9xxx_slim_probe(struct slim_device *slim)
803{
804 struct wcd9xxx *wcd9xxx;
805 struct wcd9xxx_pdata *pdata;
806 int ret = 0;
807 int sgla_retry_cnt;
808
809 dev_info(&slim->dev, "Initialized slim device %s\n", slim->name);
810 pdata = slim->dev.platform_data;
811
812 if (!pdata) {
813 dev_err(&slim->dev, "Error, no platform data\n");
814 ret = -EINVAL;
815 goto err;
816 }
817
818 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
819 if (wcd9xxx == NULL) {
820 pr_err("%s: error, allocation failed\n", __func__);
821 ret = -ENOMEM;
822 goto err;
823 }
824 if (!slim->ctrl) {
825 pr_err("Error, no SLIMBUS control data\n");
826 ret = -EINVAL;
827 goto err_codec;
828 }
829 wcd9xxx->slim = slim;
830 slim_set_clientdata(slim, wcd9xxx);
831 wcd9xxx->reset_gpio = pdata->reset_gpio;
832 wcd9xxx->dev = &slim->dev;
833
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700834 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530835 if (ret)
836 goto err_codec;
837 usleep_range(5, 5);
838
839 ret = wcd9xxx_reset(wcd9xxx);
840 if (ret) {
841 pr_err("%s: Resetting Codec failed\n", __func__);
842 goto err_supplies;
843 }
844
845 ret = slim_get_logical_addr(wcd9xxx->slim, wcd9xxx->slim->e_addr,
846 ARRAY_SIZE(wcd9xxx->slim->e_addr), &wcd9xxx->slim->laddr);
847 if (ret) {
848 pr_err("fail to get slimbus logical address %d\n", ret);
849 goto err_reset;
850 }
851 wcd9xxx->read_dev = wcd9xxx_slim_read_device;
852 wcd9xxx->write_dev = wcd9xxx_slim_write_device;
853 wcd9xxx->irq = pdata->irq;
854 wcd9xxx->irq_base = pdata->irq_base;
855 wcd9xxx_pgd_la = wcd9xxx->slim->laddr;
856
857 if (pdata->num_irqs < TABLA_NUM_IRQS) {
858 pr_err("%s: Error, not enough interrupt lines allocated\n",
859 __func__);
860 goto err_reset;
861 }
862
863 wcd9xxx->slim_slave = &pdata->slimbus_slave_device;
864
865 ret = slim_add_device(slim->ctrl, wcd9xxx->slim_slave);
866 if (ret) {
867 pr_err("%s: error, adding SLIMBUS device failed\n", __func__);
868 goto err_reset;
869 }
870
871 sgla_retry_cnt = 0;
872
873 while (1) {
874 ret = slim_get_logical_addr(wcd9xxx->slim_slave,
875 wcd9xxx->slim_slave->e_addr,
876 ARRAY_SIZE(wcd9xxx->slim_slave->e_addr),
877 &wcd9xxx->slim_slave->laddr);
878 if (ret) {
879 if (sgla_retry_cnt++ < WCD9XXX_SLIM_GLA_MAX_RETRIES) {
880 /* Give SLIMBUS slave time to report present
881 and be ready.
882 */
883 usleep_range(1000, 1000);
884 pr_debug("%s: retry slim_get_logical_addr()\n",
885 __func__);
886 continue;
887 }
888 pr_err("fail to get slimbus slave logical address"
889 " %d\n", ret);
890 goto err_slim_add;
891 }
892 break;
893 }
894 wcd9xxx_inf_la = wcd9xxx->slim_slave->laddr;
895 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_SLIMBUS;
896
897 ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
898 if (ret) {
899 pr_err("%s: error, initializing device failed\n", __func__);
900 goto err_slim_add;
901 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530902 wcd9xxx_init_slimslave(wcd9xxx, wcd9xxx_pgd_la);
903#ifdef CONFIG_DEBUG_FS
904 debugCodec = wcd9xxx;
905
906 debugfs_wcd9xxx_dent = debugfs_create_dir
907 ("wcd9310_slimbus_interface_device", 0);
908 if (!IS_ERR(debugfs_wcd9xxx_dent)) {
909 debugfs_peek = debugfs_create_file("peek",
910 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
911 (void *) "peek", &codec_debug_ops);
912
913 debugfs_poke = debugfs_create_file("poke",
914 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
915 (void *) "poke", &codec_debug_ops);
916 }
917#endif
918
919 return ret;
920
921err_slim_add:
922 slim_remove_device(wcd9xxx->slim_slave);
923err_reset:
924 wcd9xxx_free_reset(wcd9xxx);
925err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -0700926 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530927err_codec:
928 kfree(wcd9xxx);
929err:
930 return ret;
931}
932static int wcd9xxx_slim_remove(struct slim_device *pdev)
933{
934 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -0700935 struct wcd9xxx_pdata *pdata = pdev->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530936
937#ifdef CONFIG_DEBUG_FS
938 debugfs_remove(debugfs_peek);
939 debugfs_remove(debugfs_poke);
940 debugfs_remove(debugfs_wcd9xxx_dent);
941#endif
942 wcd9xxx = slim_get_devicedata(pdev);
943 wcd9xxx_deinit_slimslave(wcd9xxx);
944 slim_remove_device(wcd9xxx->slim_slave);
Venkat Sudhir49203862012-05-21 14:29:13 -0700945 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530946 wcd9xxx_device_exit(wcd9xxx);
947 return 0;
948}
949
950static int wcd9xxx_resume(struct wcd9xxx *wcd9xxx)
951{
952 int ret = 0;
953
954 pr_debug("%s: enter\n", __func__);
955 mutex_lock(&wcd9xxx->pm_lock);
956 if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
957 pr_debug("%s: resuming system, state %d, wlock %d\n", __func__,
958 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
959 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
960 } else {
961 pr_warn("%s: system is already awake, state %d wlock %d\n",
962 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
963 }
964 mutex_unlock(&wcd9xxx->pm_lock);
965 wake_up_all(&wcd9xxx->pm_wq);
966
967 return ret;
968}
969
970static int wcd9xxx_slim_resume(struct slim_device *sldev)
971{
972 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
973 return wcd9xxx_resume(wcd9xxx);
974}
975
976static int wcd9xxx_i2c_resume(struct i2c_client *i2cdev)
977{
978 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530979 if (wcd9xxx)
980 return wcd9xxx_resume(wcd9xxx);
981 else
982 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530983}
984
985static int wcd9xxx_suspend(struct wcd9xxx *wcd9xxx, pm_message_t pmesg)
986{
987 int ret = 0;
988
989 pr_debug("%s: enter\n", __func__);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700990 /*
991 * pm_qos_update_request() can be called after this suspend chain call
992 * started. thus suspend can be called while lock is being held
993 */
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530994 mutex_lock(&wcd9xxx->pm_lock);
995 if (wcd9xxx->pm_state == WCD9XXX_PM_SLEEPABLE) {
996 pr_debug("%s: suspending system, state %d, wlock %d\n",
997 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
998 wcd9xxx->pm_state = WCD9XXX_PM_ASLEEP;
999 } else if (wcd9xxx->pm_state == WCD9XXX_PM_AWAKE) {
1000 /* unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE
1001 * then set to WCD9XXX_PM_ASLEEP */
1002 pr_debug("%s: waiting to suspend system, state %d, wlock %d\n",
1003 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1004 mutex_unlock(&wcd9xxx->pm_lock);
1005 if (!(wait_event_timeout(wcd9xxx->pm_wq,
1006 wcd9xxx_pm_cmpxchg(wcd9xxx,
1007 WCD9XXX_PM_SLEEPABLE,
1008 WCD9XXX_PM_ASLEEP) ==
1009 WCD9XXX_PM_SLEEPABLE,
1010 HZ))) {
1011 pr_debug("%s: suspend failed state %d, wlock %d\n",
1012 __func__, wcd9xxx->pm_state,
1013 wcd9xxx->wlock_holders);
1014 ret = -EBUSY;
1015 } else {
1016 pr_debug("%s: done, state %d, wlock %d\n", __func__,
1017 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1018 }
1019 mutex_lock(&wcd9xxx->pm_lock);
1020 } else if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
1021 pr_warn("%s: system is already suspended, state %d, wlock %dn",
1022 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1023 }
1024 mutex_unlock(&wcd9xxx->pm_lock);
1025
1026 return ret;
1027}
1028
1029static int wcd9xxx_slim_suspend(struct slim_device *sldev, pm_message_t pmesg)
1030{
1031 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1032 return wcd9xxx_suspend(wcd9xxx, pmesg);
1033}
1034
1035static int wcd9xxx_i2c_suspend(struct i2c_client *i2cdev, pm_message_t pmesg)
1036{
1037 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301038 if (wcd9xxx)
1039 return wcd9xxx_suspend(wcd9xxx, pmesg);
1040 else
1041 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301042}
1043
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301044static const struct slim_device_id sitar_slimtest_id[] = {
1045 {"sitar-slim", 0},
1046 {}
1047};
1048static struct slim_driver sitar_slim_driver = {
1049 .driver = {
1050 .name = "sitar-slim",
1051 .owner = THIS_MODULE,
1052 },
1053 .probe = wcd9xxx_slim_probe,
1054 .remove = wcd9xxx_slim_remove,
1055 .id_table = sitar_slimtest_id,
1056 .resume = wcd9xxx_slim_resume,
1057 .suspend = wcd9xxx_slim_suspend,
1058};
1059
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001060static const struct slim_device_id sitar1p1_slimtest_id[] = {
1061 {"sitar1p1-slim", 0},
1062 {}
1063};
1064static struct slim_driver sitar1p1_slim_driver = {
1065 .driver = {
1066 .name = "sitar1p1-slim",
1067 .owner = THIS_MODULE,
1068 },
1069 .probe = wcd9xxx_slim_probe,
1070 .remove = wcd9xxx_slim_remove,
1071 .id_table = sitar1p1_slimtest_id,
1072 .resume = wcd9xxx_slim_resume,
1073 .suspend = wcd9xxx_slim_suspend,
1074};
1075
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301076static const struct slim_device_id slimtest_id[] = {
1077 {"tabla-slim", 0},
1078 {}
1079};
1080
1081static struct slim_driver tabla_slim_driver = {
1082 .driver = {
1083 .name = "tabla-slim",
1084 .owner = THIS_MODULE,
1085 },
1086 .probe = wcd9xxx_slim_probe,
1087 .remove = wcd9xxx_slim_remove,
1088 .id_table = slimtest_id,
1089 .resume = wcd9xxx_slim_resume,
1090 .suspend = wcd9xxx_slim_suspend,
1091};
1092
1093static const struct slim_device_id slimtest2x_id[] = {
1094 {"tabla2x-slim", 0},
1095 {}
1096};
1097
1098static struct slim_driver tabla2x_slim_driver = {
1099 .driver = {
1100 .name = "tabla2x-slim",
1101 .owner = THIS_MODULE,
1102 },
1103 .probe = wcd9xxx_slim_probe,
1104 .remove = wcd9xxx_slim_remove,
1105 .id_table = slimtest2x_id,
1106 .resume = wcd9xxx_slim_resume,
1107 .suspend = wcd9xxx_slim_suspend,
1108};
1109
1110#define TABLA_I2C_TOP_LEVEL 0
1111#define TABLA_I2C_ANALOG 1
1112#define TABLA_I2C_DIGITAL_1 2
1113#define TABLA_I2C_DIGITAL_2 3
1114
1115static struct i2c_device_id tabla_id_table[] = {
1116 {"tabla top level", TABLA_I2C_TOP_LEVEL},
1117 {"tabla analog", TABLA_I2C_TOP_LEVEL},
1118 {"tabla digital1", TABLA_I2C_TOP_LEVEL},
1119 {"tabla digital2", TABLA_I2C_TOP_LEVEL},
1120 {}
1121};
1122MODULE_DEVICE_TABLE(i2c, tabla_id_table);
1123
1124static struct i2c_driver tabla_i2c_driver = {
1125 .driver = {
1126 .owner = THIS_MODULE,
1127 .name = "tabla-i2c-core",
1128 },
1129 .id_table = tabla_id_table,
1130 .probe = wcd9xxx_i2c_probe,
1131 .remove = __devexit_p(wcd9xxx_i2c_remove),
1132 .resume = wcd9xxx_i2c_resume,
1133 .suspend = wcd9xxx_i2c_suspend,
1134};
1135
1136static int __init wcd9xxx_init(void)
1137{
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001138 int ret1, ret2, ret3, ret4, ret5;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301139
1140 ret1 = slim_driver_register(&tabla_slim_driver);
1141 if (ret1 != 0)
1142 pr_err("Failed to register tabla SB driver: %d\n", ret1);
1143
1144 ret2 = slim_driver_register(&tabla2x_slim_driver);
1145 if (ret2 != 0)
1146 pr_err("Failed to register tabla2x SB driver: %d\n", ret2);
1147
1148 ret3 = i2c_add_driver(&tabla_i2c_driver);
1149 if (ret3 != 0)
1150 pr_err("failed to add the I2C driver\n");
1151
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301152 ret4 = slim_driver_register(&sitar_slim_driver);
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001153 if (ret4 != 0)
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301154 pr_err("Failed to register sitar SB driver: %d\n", ret4);
1155
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001156 ret5 = slim_driver_register(&sitar1p1_slim_driver);
1157 if (ret5 != 0)
1158 pr_err("Failed to register sitar SB driver: %d\n", ret5);
1159
1160 return (ret1 && ret2 && ret3 && ret4 && ret5) ? -1 : 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301161}
1162module_init(wcd9xxx_init);
1163
1164static void __exit wcd9xxx_exit(void)
1165{
1166}
1167module_exit(wcd9xxx_exit);
1168
1169MODULE_DESCRIPTION("Codec core driver");
1170MODULE_VERSION("1.0");
1171MODULE_LICENSE("GPL v2");