blob: 05707fd2862a90c382fd869b44c7b253418f3c4d [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>
Kiran Kandi725f8492012-08-06 13:45:16 -070015#include <linux/of_gpio.h>
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053016#include <linux/slab.h>
17#include <linux/mfd/core.h>
18#include <linux/mfd/wcd9xxx/wcd9xxx-slimslave.h>
19#include <linux/mfd/wcd9xxx/core.h>
20#include <linux/mfd/wcd9xxx/pdata.h>
21#include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
22
23#include <linux/delay.h>
24#include <linux/gpio.h>
25#include <linux/debugfs.h>
26#include <linux/regulator/consumer.h>
27#include <linux/i2c.h>
28#include <sound/soc.h>
29
30#define WCD9XXX_SLIM_GLA_MAX_RETRIES 5
31#define WCD9XXX_REGISTER_START_OFFSET 0x800
32#define WCD9XXX_SLIM_RW_MAX_TRIES 3
33
34#define MAX_WCD9XXX_DEVICE 4
Asish Bhattacharya2b709d42011-11-15 10:39:23 +053035#define TABLA_I2C_MODE 0x03
36#define SITAR_I2C_MODE 0x01
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053037
38struct wcd9xxx_i2c {
39 struct i2c_client *client;
40 struct i2c_msg xfer_msg[2];
41 struct mutex xfer_lock;
42 int mod_id;
43};
44
45struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -070046static int wcd9xxx_intf = -1;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053047
48static int wcd9xxx_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
49 int bytes, void *dest, bool interface_reg)
50{
51 int ret;
52 u8 *buf = dest;
53
54 if (bytes <= 0) {
55 dev_err(wcd9xxx->dev, "Invalid byte read length %d\n", bytes);
56 return -EINVAL;
57 }
58
59 ret = wcd9xxx->read_dev(wcd9xxx, reg, bytes, dest, interface_reg);
60 if (ret < 0) {
61 dev_err(wcd9xxx->dev, "Codec read failed\n");
62 return ret;
63 } else
Kiran Kandi1e6371d2012-03-29 11:48:57 -070064 dev_dbg(wcd9xxx->dev, "Read 0x%02x from 0x%x\n",
65 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053066
67 return 0;
68}
69int wcd9xxx_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
70{
71 u8 val;
72 int ret;
73
74 mutex_lock(&wcd9xxx->io_lock);
75 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, false);
76 mutex_unlock(&wcd9xxx->io_lock);
77
78 if (ret < 0)
79 return ret;
80 else
81 return val;
82}
83EXPORT_SYMBOL_GPL(wcd9xxx_reg_read);
84
85static int wcd9xxx_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
86 int bytes, void *src, bool interface_reg)
87{
88 u8 *buf = src;
89
90 if (bytes <= 0) {
91 pr_err("%s: Error, invalid write length\n", __func__);
92 return -EINVAL;
93 }
94
Kiran Kandi1e6371d2012-03-29 11:48:57 -070095 dev_dbg(wcd9xxx->dev, "Write %02x to 0x%x\n",
96 *buf, reg);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +053097
98 return wcd9xxx->write_dev(wcd9xxx, reg, bytes, src, interface_reg);
99}
100
101int wcd9xxx_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
102 u8 val)
103{
104 int ret;
105
106 mutex_lock(&wcd9xxx->io_lock);
107 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, false);
108 mutex_unlock(&wcd9xxx->io_lock);
109
110 return ret;
111}
112EXPORT_SYMBOL_GPL(wcd9xxx_reg_write);
113
114static u8 wcd9xxx_pgd_la;
115static u8 wcd9xxx_inf_la;
116
117int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg)
118{
119 u8 val;
120 int ret;
121
122 mutex_lock(&wcd9xxx->io_lock);
123 ret = wcd9xxx_read(wcd9xxx, reg, 1, &val, true);
124 mutex_unlock(&wcd9xxx->io_lock);
125
126 if (ret < 0)
127 return ret;
128 else
129 return val;
130}
131EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_read);
132
133int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
134 u8 val)
135{
136 int ret;
137
138 mutex_lock(&wcd9xxx->io_lock);
139 ret = wcd9xxx_write(wcd9xxx, reg, 1, &val, true);
140 mutex_unlock(&wcd9xxx->io_lock);
141
142 return ret;
143}
144EXPORT_SYMBOL_GPL(wcd9xxx_interface_reg_write);
145
146int wcd9xxx_bulk_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
147 int count, u8 *buf)
148{
149 int ret;
150
151 mutex_lock(&wcd9xxx->io_lock);
152
153 ret = wcd9xxx_read(wcd9xxx, reg, count, buf, false);
154
155 mutex_unlock(&wcd9xxx->io_lock);
156
157 return ret;
158}
159EXPORT_SYMBOL_GPL(wcd9xxx_bulk_read);
160
161int wcd9xxx_bulk_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
162 int count, u8 *buf)
163{
164 int ret;
165
166 mutex_lock(&wcd9xxx->io_lock);
167
168 ret = wcd9xxx_write(wcd9xxx, reg, count, buf, false);
169
170 mutex_unlock(&wcd9xxx->io_lock);
171
172 return ret;
173}
174EXPORT_SYMBOL_GPL(wcd9xxx_bulk_write);
175
176static int wcd9xxx_slim_read_device(struct wcd9xxx *wcd9xxx, unsigned short reg,
177 int bytes, void *dest, bool interface)
178{
179 int ret;
180 struct slim_ele_access msg;
181 int slim_read_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
182 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
183 msg.num_bytes = bytes;
184 msg.comp = NULL;
185
186 while (1) {
187 mutex_lock(&wcd9xxx->xfer_lock);
188 ret = slim_request_val_element(interface ?
189 wcd9xxx->slim_slave : wcd9xxx->slim,
190 &msg, dest, bytes);
191 mutex_unlock(&wcd9xxx->xfer_lock);
192 if (likely(ret == 0) || (--slim_read_tries == 0))
193 break;
194 usleep_range(5000, 5000);
195 }
196
197 if (ret)
198 pr_err("%s: Error, Codec read failed (%d)\n", __func__, ret);
199
200 return ret;
201}
202/* Interface specifies whether the write is to the interface or general
203 * registers.
204 */
205static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx,
206 unsigned short reg, int bytes, void *src, bool interface)
207{
208 int ret;
209 struct slim_ele_access msg;
210 int slim_write_tries = WCD9XXX_SLIM_RW_MAX_TRIES;
211 msg.start_offset = WCD9XXX_REGISTER_START_OFFSET + reg;
212 msg.num_bytes = bytes;
213 msg.comp = NULL;
214
215 while (1) {
216 mutex_lock(&wcd9xxx->xfer_lock);
217 ret = slim_change_val_element(interface ?
218 wcd9xxx->slim_slave : wcd9xxx->slim,
219 &msg, src, bytes);
220 mutex_unlock(&wcd9xxx->xfer_lock);
221 if (likely(ret == 0) || (--slim_write_tries == 0))
222 break;
223 usleep_range(5000, 5000);
224 }
225
226 if (ret)
227 pr_err("%s: Error, Codec write failed (%d)\n", __func__, ret);
228
229 return ret;
230}
231
232static struct mfd_cell tabla1x_devs[] = {
233 {
234 .name = "tabla1x_codec",
235 },
236};
237
238static struct mfd_cell tabla_devs[] = {
239 {
240 .name = "tabla_codec",
241 },
242};
243
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530244static struct mfd_cell sitar_devs[] = {
245 {
246 .name = "sitar_codec",
247 },
248};
249
Joonwoo Parka7172112012-07-23 16:03:49 -0700250static struct mfd_cell taiko_devs[] = {
251 {
252 .name = "taiko_codec",
253 },
254};
255
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530256static void wcd9xxx_bring_up(struct wcd9xxx *wcd9xxx)
257{
258 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x4);
259 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 0);
260 usleep_range(5000, 5000);
261 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_CDC_CTL, 3);
262 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 3);
263}
264
265static void wcd9xxx_bring_down(struct wcd9xxx *wcd9xxx)
266{
267 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x7);
268 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x6);
269 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0xe);
270 wcd9xxx_reg_write(wcd9xxx, WCD9XXX_A_LEAKAGE_CTL, 0x8);
271}
272
273static int wcd9xxx_reset(struct wcd9xxx *wcd9xxx)
274{
275 int ret;
276
277 if (wcd9xxx->reset_gpio) {
278 ret = gpio_request(wcd9xxx->reset_gpio, "CDC_RESET");
279 if (ret) {
280 pr_err("%s: Failed to request gpio %d\n", __func__,
281 wcd9xxx->reset_gpio);
282 wcd9xxx->reset_gpio = 0;
283 return ret;
284 }
285
286 gpio_direction_output(wcd9xxx->reset_gpio, 1);
287 msleep(20);
288 gpio_direction_output(wcd9xxx->reset_gpio, 0);
289 msleep(20);
290 gpio_direction_output(wcd9xxx->reset_gpio, 1);
291 msleep(20);
292 }
293 return 0;
294}
295
296static void wcd9xxx_free_reset(struct wcd9xxx *wcd9xxx)
297{
298 if (wcd9xxx->reset_gpio) {
299 gpio_free(wcd9xxx->reset_gpio);
300 wcd9xxx->reset_gpio = 0;
301 }
302}
303
304static int wcd9xxx_device_init(struct wcd9xxx *wcd9xxx, int irq)
305{
306 int ret;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530307 struct mfd_cell *wcd9xxx_dev = NULL;
308 int wcd9xxx_dev_size = 0;
309
310 mutex_init(&wcd9xxx->io_lock);
311 mutex_init(&wcd9xxx->xfer_lock);
312
313 mutex_init(&wcd9xxx->pm_lock);
314 wcd9xxx->wlock_holders = 0;
315 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
316 init_waitqueue_head(&wcd9xxx->pm_wq);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700317 pm_qos_add_request(&wcd9xxx->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
318 PM_QOS_DEFAULT_VALUE);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530319
320 dev_set_drvdata(wcd9xxx->dev, wcd9xxx);
321
322 wcd9xxx_bring_up(wcd9xxx);
323
Kiran Kandi725f8492012-08-06 13:45:16 -0700324 if (wcd9xxx->irq != -1) {
325 ret = wcd9xxx_irq_init(wcd9xxx);
326 if (ret) {
327 pr_err("IRQ initialization failed\n");
328 goto err;
329 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530330 }
331
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530332 wcd9xxx->idbyte_0 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_0);
333 wcd9xxx->idbyte_1 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_1);
334 wcd9xxx->idbyte_2 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_2);
335 wcd9xxx->idbyte_3 = wcd9xxx_reg_read(wcd9xxx, WCD9XXX_A_CHIP_ID_BYTE_3);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530336
337 wcd9xxx->version = wcd9xxx_reg_read(wcd9xxx,
338 WCD9XXX_A_CHIP_VERSION) & 0x1F;
339 pr_info("%s : Codec version %u initialized\n",
340 __func__, wcd9xxx->version);
341
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530342 if (wcd9xxx->idbyte_0 == 0x2) {
343 wcd9xxx_dev = tabla_devs;
344 wcd9xxx_dev_size = ARRAY_SIZE(tabla_devs);
345 } else if (wcd9xxx->idbyte_0 == 0x1) {
346 wcd9xxx_dev = tabla1x_devs;
347 wcd9xxx_dev_size = ARRAY_SIZE(tabla1x_devs);
Joonwoo Parka7172112012-07-23 16:03:49 -0700348 } else if (wcd9xxx->idbyte_0 == 0x0 && wcd9xxx->idbyte_1 == 0x0 &&
349 wcd9xxx->idbyte_2 == 0x2 && wcd9xxx->idbyte_3 == 0x1) {
350 wcd9xxx_dev = taiko_devs;
351 wcd9xxx_dev_size = ARRAY_SIZE(taiko_devs);
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530352 } else if (wcd9xxx->idbyte_0 == 0x0) {
353 wcd9xxx_dev = sitar_devs;
354 wcd9xxx_dev_size = ARRAY_SIZE(sitar_devs);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530355 }
Joonwoo Parka7172112012-07-23 16:03:49 -0700356 ret = mfd_add_devices(wcd9xxx->dev, -1, wcd9xxx_dev, wcd9xxx_dev_size,
357 NULL, 0);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530358 if (ret != 0) {
359 dev_err(wcd9xxx->dev, "Failed to add children: %d\n", ret);
360 goto err_irq;
361 }
362 return ret;
363err_irq:
364 wcd9xxx_irq_exit(wcd9xxx);
365err:
366 wcd9xxx_bring_down(wcd9xxx);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700367 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530368 mutex_destroy(&wcd9xxx->pm_lock);
369 mutex_destroy(&wcd9xxx->io_lock);
370 mutex_destroy(&wcd9xxx->xfer_lock);
371 return ret;
372}
373
374static void wcd9xxx_device_exit(struct wcd9xxx *wcd9xxx)
375{
376 wcd9xxx_irq_exit(wcd9xxx);
377 wcd9xxx_bring_down(wcd9xxx);
378 wcd9xxx_free_reset(wcd9xxx);
379 mutex_destroy(&wcd9xxx->pm_lock);
Stephen Boyd2fcabf92012-05-30 10:41:11 -0700380 pm_qos_remove_request(&wcd9xxx->pm_qos_req);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530381 mutex_destroy(&wcd9xxx->io_lock);
382 mutex_destroy(&wcd9xxx->xfer_lock);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700383 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS)
384 slim_remove_device(wcd9xxx->slim_slave);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530385 kfree(wcd9xxx);
386}
387
388
389#ifdef CONFIG_DEBUG_FS
390struct wcd9xxx *debugCodec;
391
392static struct dentry *debugfs_wcd9xxx_dent;
393static struct dentry *debugfs_peek;
394static struct dentry *debugfs_poke;
395
396static unsigned char read_data;
397
398static int codec_debug_open(struct inode *inode, struct file *file)
399{
400 file->private_data = inode->i_private;
401 return 0;
402}
403
404static int get_parameters(char *buf, long int *param1, int num_of_par)
405{
406 char *token;
407 int base, cnt;
408
409 token = strsep(&buf, " ");
410
411 for (cnt = 0; cnt < num_of_par; cnt++) {
412 if (token != NULL) {
413 if ((token[1] == 'x') || (token[1] == 'X'))
414 base = 16;
415 else
416 base = 10;
417
418 if (strict_strtoul(token, base, &param1[cnt]) != 0)
419 return -EINVAL;
420
421 token = strsep(&buf, " ");
422 } else
423 return -EINVAL;
424 }
425 return 0;
426}
427
428static ssize_t codec_debug_read(struct file *file, char __user *ubuf,
429 size_t count, loff_t *ppos)
430{
431 char lbuf[8];
432
433 snprintf(lbuf, sizeof(lbuf), "0x%x\n", read_data);
434 return simple_read_from_buffer(ubuf, count, ppos, lbuf,
435 strnlen(lbuf, 7));
436}
437
438
439static ssize_t codec_debug_write(struct file *filp,
440 const char __user *ubuf, size_t cnt, loff_t *ppos)
441{
442 char *access_str = filp->private_data;
443 char lbuf[32];
444 int rc;
445 long int param[5];
446
447 if (cnt > sizeof(lbuf) - 1)
448 return -EINVAL;
449
450 rc = copy_from_user(lbuf, ubuf, cnt);
451 if (rc)
452 return -EFAULT;
453
454 lbuf[cnt] = '\0';
455
456 if (!strncmp(access_str, "poke", 6)) {
457 /* write */
458 rc = get_parameters(lbuf, param, 2);
459 if ((param[0] <= 0x3FF) && (param[1] <= 0xFF) &&
460 (rc == 0))
461 wcd9xxx_interface_reg_write(debugCodec, param[0],
462 param[1]);
463 else
464 rc = -EINVAL;
465 } else if (!strncmp(access_str, "peek", 6)) {
466 /* read */
467 rc = get_parameters(lbuf, param, 1);
468 if ((param[0] <= 0x3FF) && (rc == 0))
469 read_data = wcd9xxx_interface_reg_read(debugCodec,
470 param[0]);
471 else
472 rc = -EINVAL;
473 }
474
475 if (rc == 0)
476 rc = cnt;
477 else
478 pr_err("%s: rc = %d\n", __func__, rc);
479
480 return rc;
481}
482
483static const struct file_operations codec_debug_ops = {
484 .open = codec_debug_open,
485 .write = codec_debug_write,
486 .read = codec_debug_read
487};
488#endif
489
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700490static int wcd9xxx_enable_supplies(struct wcd9xxx *wcd9xxx,
491 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530492{
493 int ret;
494 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530495 wcd9xxx->supplies = kzalloc(sizeof(struct regulator_bulk_data) *
496 ARRAY_SIZE(pdata->regulator),
497 GFP_KERNEL);
498 if (!wcd9xxx->supplies) {
499 ret = -ENOMEM;
500 goto err;
501 }
502
Kiran Kandi725f8492012-08-06 13:45:16 -0700503 wcd9xxx->num_of_supplies = 0;
504 for (i = 0; i < ARRAY_SIZE(pdata->regulator); i++) {
505 if (pdata->regulator[i].name) {
506 wcd9xxx->supplies[i].supply = pdata->regulator[i].name;
507 wcd9xxx->num_of_supplies++;
508 }
509 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530510
Kiran Kandi725f8492012-08-06 13:45:16 -0700511 ret = regulator_bulk_get(wcd9xxx->dev, wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530512 wcd9xxx->supplies);
513 if (ret != 0) {
514 dev_err(wcd9xxx->dev, "Failed to get supplies: err = %d\n",
515 ret);
516 goto err_supplies;
517 }
518
Kiran Kandi725f8492012-08-06 13:45:16 -0700519 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530520 ret = regulator_set_voltage(wcd9xxx->supplies[i].consumer,
521 pdata->regulator[i].min_uV, pdata->regulator[i].max_uV);
522 if (ret) {
523 pr_err("%s: Setting regulator voltage failed for "
524 "regulator %s err = %d\n", __func__,
525 wcd9xxx->supplies[i].supply, ret);
526 goto err_get;
527 }
528
529 ret = regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer,
530 pdata->regulator[i].optimum_uA);
531 if (ret < 0) {
532 pr_err("%s: Setting regulator optimum mode failed for "
533 "regulator %s err = %d\n", __func__,
534 wcd9xxx->supplies[i].supply, ret);
535 goto err_get;
536 }
537 }
538
Kiran Kandi725f8492012-08-06 13:45:16 -0700539 ret = regulator_bulk_enable(wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530540 wcd9xxx->supplies);
541 if (ret != 0) {
542 dev_err(wcd9xxx->dev, "Failed to enable supplies: err = %d\n",
543 ret);
544 goto err_configure;
545 }
546 return ret;
547
548err_configure:
Kiran Kandi725f8492012-08-06 13:45:16 -0700549 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530550 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
551 pdata->regulator[i].max_uV);
552 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
553 }
554err_get:
Kiran Kandi725f8492012-08-06 13:45:16 -0700555 regulator_bulk_free(wcd9xxx->num_of_supplies, wcd9xxx->supplies);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530556err_supplies:
557 kfree(wcd9xxx->supplies);
558err:
559 return ret;
560}
561
Venkat Sudhir49203862012-05-21 14:29:13 -0700562static void wcd9xxx_disable_supplies(struct wcd9xxx *wcd9xxx,
563 struct wcd9xxx_pdata *pdata)
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530564{
565 int i;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530566
Kiran Kandi725f8492012-08-06 13:45:16 -0700567 regulator_bulk_disable(wcd9xxx->num_of_supplies,
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530568 wcd9xxx->supplies);
Kiran Kandi725f8492012-08-06 13:45:16 -0700569 for (i = 0; i < wcd9xxx->num_of_supplies; i++) {
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530570 regulator_set_voltage(wcd9xxx->supplies[i].consumer, 0,
571 pdata->regulator[i].max_uV);
572 regulator_set_optimum_mode(wcd9xxx->supplies[i].consumer, 0);
573 }
Kiran Kandi725f8492012-08-06 13:45:16 -0700574 regulator_bulk_free(wcd9xxx->num_of_supplies, wcd9xxx->supplies);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530575 kfree(wcd9xxx->supplies);
576}
577
578int wcd9xxx_get_intf_type(void)
579{
580 return wcd9xxx_intf;
581}
582EXPORT_SYMBOL_GPL(wcd9xxx_get_intf_type);
583
584struct wcd9xxx_i2c *get_i2c_wcd9xxx_device_info(u16 reg)
585{
586 u16 mask = 0x0f00;
587 int value = 0;
588 struct wcd9xxx_i2c *wcd9xxx = NULL;
589 value = ((reg & mask) >> 8) & 0x000f;
590 switch (value) {
591 case 0:
592 wcd9xxx = &wcd9xxx_modules[0];
593 break;
594 case 1:
595 wcd9xxx = &wcd9xxx_modules[1];
596 break;
597 case 2:
598 wcd9xxx = &wcd9xxx_modules[2];
599 break;
600 case 3:
601 wcd9xxx = &wcd9xxx_modules[3];
602 break;
603 default:
604 break;
605 }
606 return wcd9xxx;
607}
608
609int wcd9xxx_i2c_write_device(u16 reg, u8 *value,
610 u32 bytes)
611{
612
613 struct i2c_msg *msg;
614 int ret = 0;
615 u8 reg_addr = 0;
616 u8 data[bytes + 1];
617 struct wcd9xxx_i2c *wcd9xxx;
618
619 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
620 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
621 pr_err("failed to get device info\n");
622 return -ENODEV;
623 }
624 reg_addr = (u8)reg;
625 msg = &wcd9xxx->xfer_msg[0];
626 msg->addr = wcd9xxx->client->addr;
627 msg->len = bytes + 1;
628 msg->flags = 0;
629 data[0] = reg;
630 data[1] = *value;
631 msg->buf = data;
632 ret = i2c_transfer(wcd9xxx->client->adapter, wcd9xxx->xfer_msg, 1);
633 /* Try again if the write fails */
634 if (ret != 1) {
635 ret = i2c_transfer(wcd9xxx->client->adapter,
636 wcd9xxx->xfer_msg, 1);
637 if (ret != 1) {
638 pr_err("failed to write the device\n");
639 return ret;
640 }
641 }
642 pr_debug("write sucess register = %x val = %x\n", reg, data[1]);
643 return 0;
644}
645
646
647int wcd9xxx_i2c_read_device(unsigned short reg,
648 int bytes, unsigned char *dest)
649{
650 struct i2c_msg *msg;
651 int ret = 0;
652 u8 reg_addr = 0;
653 struct wcd9xxx_i2c *wcd9xxx;
654 u8 i = 0;
655
656 wcd9xxx = get_i2c_wcd9xxx_device_info(reg);
657 if (wcd9xxx == NULL || wcd9xxx->client == NULL) {
658 pr_err("failed to get device info\n");
659 return -ENODEV;
660 }
661 for (i = 0; i < bytes; i++) {
662 reg_addr = (u8)reg++;
663 msg = &wcd9xxx->xfer_msg[0];
664 msg->addr = wcd9xxx->client->addr;
665 msg->len = 1;
666 msg->flags = 0;
667 msg->buf = &reg_addr;
668
669 msg = &wcd9xxx->xfer_msg[1];
670 msg->addr = wcd9xxx->client->addr;
671 msg->len = 1;
672 msg->flags = I2C_M_RD;
673 msg->buf = dest++;
674 ret = i2c_transfer(wcd9xxx->client->adapter,
675 wcd9xxx->xfer_msg, 2);
676
677 /* Try again if read fails first time */
678 if (ret != 2) {
679 ret = i2c_transfer(wcd9xxx->client->adapter,
680 wcd9xxx->xfer_msg, 2);
681 if (ret != 2) {
682 pr_err("failed to read wcd9xxx register\n");
683 return ret;
684 }
685 }
686 }
687 return 0;
688}
689
690int wcd9xxx_i2c_read(struct wcd9xxx *wcd9xxx, unsigned short reg,
691 int bytes, void *dest, bool interface_reg)
692{
693 return wcd9xxx_i2c_read_device(reg, bytes, dest);
694}
695
696int wcd9xxx_i2c_write(struct wcd9xxx *wcd9xxx, unsigned short reg,
697 int bytes, void *src, bool interface_reg)
698{
699 return wcd9xxx_i2c_write_device(reg, src, bytes);
700}
701
702static int __devinit wcd9xxx_i2c_probe(struct i2c_client *client,
703 const struct i2c_device_id *id)
704{
705 struct wcd9xxx *wcd9xxx;
Venkat Sudhircbd522c2012-07-13 09:46:29 -0700706 struct wcd9xxx_pdata *pdata;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530707 int val = 0;
708 int ret = 0;
Asish Bhattacharya2b709d42011-11-15 10:39:23 +0530709 int i2c_mode = 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530710 static int device_id;
711
Asish Bhattacharya2b709d42011-11-15 10:39:23 +0530712 pr_info("%s\n", __func__);
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700713 if (wcd9xxx_intf == WCD9XXX_INTERFACE_TYPE_SLIMBUS) {
714 pr_info("tabla card is already detected in slimbus mode\n");
715 return -ENODEV;
716 }
Venkat Sudhircbd522c2012-07-13 09:46:29 -0700717 pdata = client->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530718 if (device_id > 0) {
719 wcd9xxx_modules[device_id++].client = client;
720 pr_info("probe for other slaves devices of tabla\n");
721 return ret;
722 }
723
724 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
725 if (wcd9xxx == NULL) {
726 pr_err("%s: error, allocation failed\n", __func__);
727 ret = -ENOMEM;
728 goto fail;
729 }
730
731 if (!pdata) {
732 dev_dbg(&client->dev, "no platform data?\n");
733 ret = -EINVAL;
734 goto fail;
735 }
736 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
737 dev_dbg(&client->dev, "can't talk I2C?\n");
738 ret = -EIO;
739 goto fail;
740 }
Asish Bhattacharyab86c3472012-02-15 08:31:52 +0530741 dev_set_drvdata(&client->dev, wcd9xxx);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530742 wcd9xxx->dev = &client->dev;
743 wcd9xxx->reset_gpio = pdata->reset_gpio;
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -0700744 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530745 if (ret) {
746 pr_err("%s: Fail to enable Codec supplies\n", __func__);
747 goto err_codec;
748 }
749
750 usleep_range(5, 5);
751 ret = wcd9xxx_reset(wcd9xxx);
752 if (ret) {
753 pr_err("%s: Resetting Codec failed\n", __func__);
754 goto err_supplies;
755 }
756 wcd9xxx_modules[device_id++].client = client;
757
758 wcd9xxx->read_dev = wcd9xxx_i2c_read;
759 wcd9xxx->write_dev = wcd9xxx_i2c_write;
760 wcd9xxx->irq = pdata->irq;
761 wcd9xxx->irq_base = pdata->irq_base;
762
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530763 ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
764 if (ret) {
765 pr_err("%s: error, initializing device failed\n", __func__);
766 goto err_device_init;
767 }
Asish Bhattacharya6dd4cb52012-07-05 19:47:42 +0530768
769 if ((wcd9xxx->idbyte_0 == 0x2) || (wcd9xxx->idbyte_0 == 0x1))
770 i2c_mode = TABLA_I2C_MODE;
771 else if (wcd9xxx->idbyte_0 == 0x0)
772 i2c_mode = SITAR_I2C_MODE;
773
774 ret = wcd9xxx_read(wcd9xxx, WCD9XXX_A_CHIP_STATUS, 1, &val, 0);
775
776 if ((ret < 0) || (val != i2c_mode))
777 pr_err("failed to read the wcd9xxx status ret = %d\n", ret);
778
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530779 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_I2C;
780
781 return ret;
782err_device_init:
783 wcd9xxx_free_reset(wcd9xxx);
784err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -0700785 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530786err_codec:
787 kfree(wcd9xxx);
788fail:
789 return ret;
790}
791
792static int __devexit wcd9xxx_i2c_remove(struct i2c_client *client)
793{
794 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -0700795 struct wcd9xxx_pdata *pdata = client->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530796 pr_debug("exit\n");
797 wcd9xxx = dev_get_drvdata(&client->dev);
Venkat Sudhir49203862012-05-21 14:29:13 -0700798 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +0530799 wcd9xxx_device_exit(wcd9xxx);
800 return 0;
801}
802
Kiran Kandi725f8492012-08-06 13:45:16 -0700803#define CODEC_DT_MAX_PROP_SIZE 40
804static int wcd9xxx_dt_parse_vreg_info(struct device *dev,
805 struct wcd9xxx_regulator *vreg, const char *vreg_name)
806{
807 int len, ret = 0;
808 const __be32 *prop;
809 char prop_name[CODEC_DT_MAX_PROP_SIZE];
810 struct device_node *regnode = NULL;
811 u32 prop_val;
812
813 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE, "%s-supply",
814 vreg_name);
815 regnode = of_parse_phandle(dev->of_node, prop_name, 0);
816
817 if (!regnode) {
818 dev_err(dev, "Looking up %s property in node %s failed",
819 prop_name, dev->of_node->full_name);
820 return -ENODEV;
821 }
822 vreg->name = vreg_name;
823
824 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
825 "qcom,%s-voltage", vreg_name);
826 prop = of_get_property(dev->of_node, prop_name, &len);
827
828 if (!prop || (len != (2 * sizeof(__be32)))) {
829 dev_err(dev, "%s %s property\n",
830 prop ? "invalid format" : "no", prop_name);
831 return -ENODEV;
832 } else {
833 vreg->min_uV = be32_to_cpup(&prop[0]);
834 vreg->max_uV = be32_to_cpup(&prop[1]);
835 }
836
837 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
838 "qcom,%s-current", vreg_name);
839
840 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
841 if (ret) {
842 dev_err(dev, "Looking up %s property in node %s failed",
843 prop_name, dev->of_node->full_name);
844 return -ENODEV;
845 }
846 vreg->optimum_uA = prop_val;
847
848 dev_info(dev, "%s: vol=[%d %d]uV, curr=[%d]uA\n", vreg->name,
849 vreg->min_uV, vreg->max_uV, vreg->optimum_uA);
850 return 0;
851}
852
853static int wcd9xxx_dt_parse_micbias_info(struct device *dev,
854 struct wcd9xxx_micbias_setting *micbias)
855{
856 int ret = 0;
857 char prop_name[CODEC_DT_MAX_PROP_SIZE];
858 u32 prop_val;
859
860 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
861 "qcom,cdc-micbias-ldoh-v");
862 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
863 if (ret) {
864 dev_err(dev, "Looking up %s property in node %s failed",
865 prop_name, dev->of_node->full_name);
866 return -ENODEV;
867 }
868 micbias->ldoh_v = (u8)prop_val;
869
870 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
871 "qcom,cdc-micbias-cfilt1-mv");
872 ret = of_property_read_u32(dev->of_node, prop_name,
873 &micbias->cfilt1_mv);
874 if (ret) {
875 dev_err(dev, "Looking up %s property in node %s failed",
876 prop_name, dev->of_node->full_name);
877 return -ENODEV;
878 }
879
880 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
881 "qcom,cdc-micbias-cfilt2-mv");
882 ret = of_property_read_u32(dev->of_node, prop_name,
883 &micbias->cfilt2_mv);
884 if (ret) {
885 dev_err(dev, "Looking up %s property in node %s failed",
886 prop_name, dev->of_node->full_name);
887 return -ENODEV;
888 }
889
890 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
891 "qcom,cdc-micbias-cfilt3-mv");
892 ret = of_property_read_u32(dev->of_node, prop_name,
893 &micbias->cfilt3_mv);
894 if (ret) {
895 dev_err(dev, "Looking up %s property in node %s failed",
896 prop_name, dev->of_node->full_name);
897 return -ENODEV;
898 }
899
900 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
901 "qcom,cdc-micbias1-cfilt-sel");
902 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
903 if (ret) {
904 dev_err(dev, "Looking up %s property in node %s failed",
905 prop_name, dev->of_node->full_name);
906 return -ENODEV;
907 }
908 micbias->bias1_cfilt_sel = (u8)prop_val;
909
910 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
911 "qcom,cdc-micbias2-cfilt-sel");
912 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
913 if (ret) {
914 dev_err(dev, "Looking up %s property in node %s failed",
915 prop_name, dev->of_node->full_name);
916 return -ENODEV;
917 }
918 micbias->bias2_cfilt_sel = (u8)prop_val;
919
920 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
921 "qcom,cdc-micbias3-cfilt-sel");
922 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
923 if (ret) {
924 dev_err(dev, "Looking up %s property in node %s failed",
925 prop_name, dev->of_node->full_name);
926 return -ENODEV;
927 }
928 micbias->bias3_cfilt_sel = (u8)prop_val;
929
930 snprintf(prop_name, CODEC_DT_MAX_PROP_SIZE,
931 "qcom,cdc-micbias4-cfilt-sel");
932 ret = of_property_read_u32(dev->of_node, prop_name, &prop_val);
933 if (ret) {
934 dev_err(dev, "Looking up %s property in node %s failed",
935 prop_name, dev->of_node->full_name);
936 return -ENODEV;
937 }
938 micbias->bias4_cfilt_sel = (u8)prop_val;
939
940 dev_dbg(dev, "ldoh_v %u cfilt1_mv %u cfilt2_mv %u cfilt3_mv %u",
941 (u32)micbias->ldoh_v, (u32)micbias->cfilt1_mv,
942 (u32)micbias->cfilt2_mv, (u32)micbias->cfilt3_mv);
943
944 dev_dbg(dev, "bias1_cfilt_sel %u bias2_cfilt_sel %u\n",
945 (u32)micbias->bias1_cfilt_sel, (u32)micbias->bias2_cfilt_sel);
946
947 dev_dbg(dev, "bias3_cfilt_sel %u bias4_cfilt_sel %u\n",
948 (u32)micbias->bias3_cfilt_sel, (u32)micbias->bias4_cfilt_sel);
949
950 return 0;
951}
952
953static int wcd9xxx_dt_parse_slim_interface_dev_info(struct device *dev,
954 struct slim_device *slim_ifd)
955{
956 int ret = 0;
957 struct property *prop;
958
959 ret = of_property_read_string(dev->of_node, "qcom,cdc-slim-ifd",
960 &slim_ifd->name);
961 if (ret) {
962 dev_err(dev, "Looking up %s property in node %s failed",
963 "qcom,cdc-slim-ifd-dev", dev->of_node->full_name);
964 return -ENODEV;
965 }
966 prop = of_find_property(dev->of_node,
967 "qcom,cdc-slim-ifd-elemental-addr", NULL);
968 if (!prop) {
969 dev_err(dev, "Looking up %s property in node %s failed",
970 "qcom,cdc-slim-ifd-elemental-addr",
971 dev->of_node->full_name);
972 return -ENODEV;
973 } else if (prop->length != 6) {
974 dev_err(dev, "invalid codec slim ifd addr. addr length = %d\n",
975 prop->length);
976 return -ENODEV;
977 }
978 memcpy(slim_ifd->e_addr, prop->value, 6);
979
980 return 0;
981}
982
983static char *taiko_supplies[] = {
984 "cdc-vdd-buck", "cdc-vdd-tx-h", "cdc-vdd-rx-h", "cdc-vddpx-1",
985 "cdc-vdd-a-1p2v", "cdc-vddcx-1", "cdc-vddcx-2",
986};
987
988static struct wcd9xxx_pdata *wcd9xxx_populate_dt_pdata(struct device *dev)
989{
990 struct wcd9xxx_pdata *pdata;
991 int ret, i;
992 char **codec_supplies;
993 u32 num_of_supplies = 0;
994
995 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
996 if (!pdata) {
997 dev_err(dev,
998 "could not allocate memory for platform data\n");
999 return NULL;
1000 }
1001
1002 if (!strcmp(dev_name(dev), "taiko-slim-pgd")) {
1003 codec_supplies = taiko_supplies;
1004 num_of_supplies = ARRAY_SIZE(taiko_supplies);
1005 } else {
1006 dev_err(dev, "%s unsupported device %s\n",
1007 __func__, dev_name(dev));
1008 goto err;
1009 }
1010
1011 if (num_of_supplies > ARRAY_SIZE(pdata->regulator)) {
1012 dev_err(dev, "%s: Num of supplies %u > max supported %u\n",
1013 __func__, num_of_supplies, ARRAY_SIZE(pdata->regulator));
1014
1015 goto err;
1016 }
1017
1018 for (i = 0; i < num_of_supplies; i++) {
1019 ret = wcd9xxx_dt_parse_vreg_info(dev, &pdata->regulator[i],
1020 codec_supplies[i]);
1021 if (ret)
1022 goto err;
1023 }
1024
1025 ret = wcd9xxx_dt_parse_micbias_info(dev, &pdata->micbias);
1026 if (ret)
1027 goto err;
1028
1029 pdata->reset_gpio = of_get_named_gpio(dev->of_node,
1030 "qcom,cdc-reset-gpio", 0);
1031 if (pdata->reset_gpio < 0) {
1032 dev_err(dev, "Looking up %s property in node %s failed %d\n",
1033 "qcom, cdc-reset-gpio", dev->of_node->full_name,
1034 pdata->reset_gpio);
1035 goto err;
1036 }
1037 pdata->irq = -1;
1038
1039 ret = wcd9xxx_dt_parse_slim_interface_dev_info(dev,
1040 &pdata->slimbus_slave_device);
1041 if (ret)
1042 goto err;
1043 return pdata;
1044err:
1045 devm_kfree(dev, pdata);
1046 return NULL;
1047}
1048
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301049static int wcd9xxx_slim_probe(struct slim_device *slim)
1050{
1051 struct wcd9xxx *wcd9xxx;
1052 struct wcd9xxx_pdata *pdata;
1053 int ret = 0;
1054 int sgla_retry_cnt;
1055
Kiran Kandi725f8492012-08-06 13:45:16 -07001056 if (slim->dev.of_node) {
1057 dev_info(&slim->dev, "Platform data from device tree\n");
1058 pdata = wcd9xxx_populate_dt_pdata(&slim->dev);
1059 slim->dev.platform_data = pdata;
1060
1061 } else {
1062 dev_info(&slim->dev, "Platform data from board file\n");
1063 pdata = slim->dev.platform_data;
1064 }
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301065
1066 if (!pdata) {
1067 dev_err(&slim->dev, "Error, no platform data\n");
1068 ret = -EINVAL;
1069 goto err;
1070 }
1071
1072 wcd9xxx = kzalloc(sizeof(struct wcd9xxx), GFP_KERNEL);
1073 if (wcd9xxx == NULL) {
1074 pr_err("%s: error, allocation failed\n", __func__);
1075 ret = -ENOMEM;
1076 goto err;
1077 }
1078 if (!slim->ctrl) {
1079 pr_err("Error, no SLIMBUS control data\n");
1080 ret = -EINVAL;
1081 goto err_codec;
1082 }
1083 wcd9xxx->slim = slim;
1084 slim_set_clientdata(slim, wcd9xxx);
1085 wcd9xxx->reset_gpio = pdata->reset_gpio;
1086 wcd9xxx->dev = &slim->dev;
1087
Venkat Sudhirdb7aa2b2012-05-15 15:06:14 -07001088 ret = wcd9xxx_enable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301089 if (ret)
1090 goto err_codec;
1091 usleep_range(5, 5);
1092
1093 ret = wcd9xxx_reset(wcd9xxx);
1094 if (ret) {
1095 pr_err("%s: Resetting Codec failed\n", __func__);
1096 goto err_supplies;
1097 }
1098
1099 ret = slim_get_logical_addr(wcd9xxx->slim, wcd9xxx->slim->e_addr,
1100 ARRAY_SIZE(wcd9xxx->slim->e_addr), &wcd9xxx->slim->laddr);
1101 if (ret) {
1102 pr_err("fail to get slimbus logical address %d\n", ret);
1103 goto err_reset;
1104 }
1105 wcd9xxx->read_dev = wcd9xxx_slim_read_device;
1106 wcd9xxx->write_dev = wcd9xxx_slim_write_device;
1107 wcd9xxx->irq = pdata->irq;
1108 wcd9xxx->irq_base = pdata->irq_base;
1109 wcd9xxx_pgd_la = wcd9xxx->slim->laddr;
1110
1111 if (pdata->num_irqs < TABLA_NUM_IRQS) {
1112 pr_err("%s: Error, not enough interrupt lines allocated\n",
1113 __func__);
1114 goto err_reset;
1115 }
1116
1117 wcd9xxx->slim_slave = &pdata->slimbus_slave_device;
1118
1119 ret = slim_add_device(slim->ctrl, wcd9xxx->slim_slave);
1120 if (ret) {
1121 pr_err("%s: error, adding SLIMBUS device failed\n", __func__);
1122 goto err_reset;
1123 }
1124
1125 sgla_retry_cnt = 0;
1126
1127 while (1) {
1128 ret = slim_get_logical_addr(wcd9xxx->slim_slave,
1129 wcd9xxx->slim_slave->e_addr,
1130 ARRAY_SIZE(wcd9xxx->slim_slave->e_addr),
1131 &wcd9xxx->slim_slave->laddr);
1132 if (ret) {
1133 if (sgla_retry_cnt++ < WCD9XXX_SLIM_GLA_MAX_RETRIES) {
1134 /* Give SLIMBUS slave time to report present
1135 and be ready.
1136 */
1137 usleep_range(1000, 1000);
1138 pr_debug("%s: retry slim_get_logical_addr()\n",
1139 __func__);
1140 continue;
1141 }
1142 pr_err("fail to get slimbus slave logical address"
1143 " %d\n", ret);
1144 goto err_slim_add;
1145 }
1146 break;
1147 }
1148 wcd9xxx_inf_la = wcd9xxx->slim_slave->laddr;
1149 wcd9xxx_intf = WCD9XXX_INTERFACE_TYPE_SLIMBUS;
1150
1151 ret = wcd9xxx_device_init(wcd9xxx, wcd9xxx->irq);
1152 if (ret) {
1153 pr_err("%s: error, initializing device failed\n", __func__);
1154 goto err_slim_add;
1155 }
Joonwoo Parka7172112012-07-23 16:03:49 -07001156
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301157 wcd9xxx_init_slimslave(wcd9xxx, wcd9xxx_pgd_la);
Joonwoo Parka7172112012-07-23 16:03:49 -07001158
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301159#ifdef CONFIG_DEBUG_FS
1160 debugCodec = wcd9xxx;
1161
1162 debugfs_wcd9xxx_dent = debugfs_create_dir
1163 ("wcd9310_slimbus_interface_device", 0);
1164 if (!IS_ERR(debugfs_wcd9xxx_dent)) {
1165 debugfs_peek = debugfs_create_file("peek",
1166 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
1167 (void *) "peek", &codec_debug_ops);
1168
1169 debugfs_poke = debugfs_create_file("poke",
1170 S_IFREG | S_IRUGO, debugfs_wcd9xxx_dent,
1171 (void *) "poke", &codec_debug_ops);
1172 }
1173#endif
1174
1175 return ret;
1176
1177err_slim_add:
1178 slim_remove_device(wcd9xxx->slim_slave);
1179err_reset:
1180 wcd9xxx_free_reset(wcd9xxx);
1181err_supplies:
Venkat Sudhir49203862012-05-21 14:29:13 -07001182 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301183err_codec:
1184 kfree(wcd9xxx);
1185err:
1186 return ret;
1187}
1188static int wcd9xxx_slim_remove(struct slim_device *pdev)
1189{
1190 struct wcd9xxx *wcd9xxx;
Venkat Sudhir49203862012-05-21 14:29:13 -07001191 struct wcd9xxx_pdata *pdata = pdev->dev.platform_data;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301192
1193#ifdef CONFIG_DEBUG_FS
1194 debugfs_remove(debugfs_peek);
1195 debugfs_remove(debugfs_poke);
1196 debugfs_remove(debugfs_wcd9xxx_dent);
1197#endif
1198 wcd9xxx = slim_get_devicedata(pdev);
1199 wcd9xxx_deinit_slimslave(wcd9xxx);
1200 slim_remove_device(wcd9xxx->slim_slave);
Venkat Sudhir49203862012-05-21 14:29:13 -07001201 wcd9xxx_disable_supplies(wcd9xxx, pdata);
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301202 wcd9xxx_device_exit(wcd9xxx);
1203 return 0;
1204}
1205
1206static int wcd9xxx_resume(struct wcd9xxx *wcd9xxx)
1207{
1208 int ret = 0;
1209
1210 pr_debug("%s: enter\n", __func__);
1211 mutex_lock(&wcd9xxx->pm_lock);
1212 if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
1213 pr_debug("%s: resuming system, state %d, wlock %d\n", __func__,
1214 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1215 wcd9xxx->pm_state = WCD9XXX_PM_SLEEPABLE;
1216 } else {
1217 pr_warn("%s: system is already awake, state %d wlock %d\n",
1218 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1219 }
1220 mutex_unlock(&wcd9xxx->pm_lock);
1221 wake_up_all(&wcd9xxx->pm_wq);
1222
1223 return ret;
1224}
1225
1226static int wcd9xxx_slim_resume(struct slim_device *sldev)
1227{
1228 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1229 return wcd9xxx_resume(wcd9xxx);
1230}
1231
1232static int wcd9xxx_i2c_resume(struct i2c_client *i2cdev)
1233{
1234 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301235 if (wcd9xxx)
1236 return wcd9xxx_resume(wcd9xxx);
1237 else
1238 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301239}
1240
1241static int wcd9xxx_suspend(struct wcd9xxx *wcd9xxx, pm_message_t pmesg)
1242{
1243 int ret = 0;
1244
1245 pr_debug("%s: enter\n", __func__);
Stephen Boyd2fcabf92012-05-30 10:41:11 -07001246 /*
1247 * pm_qos_update_request() can be called after this suspend chain call
1248 * started. thus suspend can be called while lock is being held
1249 */
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301250 mutex_lock(&wcd9xxx->pm_lock);
1251 if (wcd9xxx->pm_state == WCD9XXX_PM_SLEEPABLE) {
1252 pr_debug("%s: suspending system, state %d, wlock %d\n",
1253 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1254 wcd9xxx->pm_state = WCD9XXX_PM_ASLEEP;
1255 } else if (wcd9xxx->pm_state == WCD9XXX_PM_AWAKE) {
1256 /* unlock to wait for pm_state == WCD9XXX_PM_SLEEPABLE
1257 * then set to WCD9XXX_PM_ASLEEP */
1258 pr_debug("%s: waiting to suspend system, state %d, wlock %d\n",
1259 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1260 mutex_unlock(&wcd9xxx->pm_lock);
1261 if (!(wait_event_timeout(wcd9xxx->pm_wq,
1262 wcd9xxx_pm_cmpxchg(wcd9xxx,
1263 WCD9XXX_PM_SLEEPABLE,
1264 WCD9XXX_PM_ASLEEP) ==
1265 WCD9XXX_PM_SLEEPABLE,
1266 HZ))) {
1267 pr_debug("%s: suspend failed state %d, wlock %d\n",
1268 __func__, wcd9xxx->pm_state,
1269 wcd9xxx->wlock_holders);
1270 ret = -EBUSY;
1271 } else {
1272 pr_debug("%s: done, state %d, wlock %d\n", __func__,
1273 wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1274 }
1275 mutex_lock(&wcd9xxx->pm_lock);
1276 } else if (wcd9xxx->pm_state == WCD9XXX_PM_ASLEEP) {
1277 pr_warn("%s: system is already suspended, state %d, wlock %dn",
1278 __func__, wcd9xxx->pm_state, wcd9xxx->wlock_holders);
1279 }
1280 mutex_unlock(&wcd9xxx->pm_lock);
1281
1282 return ret;
1283}
1284
1285static int wcd9xxx_slim_suspend(struct slim_device *sldev, pm_message_t pmesg)
1286{
1287 struct wcd9xxx *wcd9xxx = slim_get_devicedata(sldev);
1288 return wcd9xxx_suspend(wcd9xxx, pmesg);
1289}
1290
1291static int wcd9xxx_i2c_suspend(struct i2c_client *i2cdev, pm_message_t pmesg)
1292{
1293 struct wcd9xxx *wcd9xxx = dev_get_drvdata(&i2cdev->dev);
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301294 if (wcd9xxx)
1295 return wcd9xxx_suspend(wcd9xxx, pmesg);
1296 else
1297 return 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301298}
1299
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301300static const struct slim_device_id sitar_slimtest_id[] = {
1301 {"sitar-slim", 0},
1302 {}
1303};
1304static struct slim_driver sitar_slim_driver = {
1305 .driver = {
1306 .name = "sitar-slim",
1307 .owner = THIS_MODULE,
1308 },
1309 .probe = wcd9xxx_slim_probe,
1310 .remove = wcd9xxx_slim_remove,
1311 .id_table = sitar_slimtest_id,
1312 .resume = wcd9xxx_slim_resume,
1313 .suspend = wcd9xxx_slim_suspend,
1314};
1315
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001316static const struct slim_device_id sitar1p1_slimtest_id[] = {
1317 {"sitar1p1-slim", 0},
1318 {}
1319};
1320static struct slim_driver sitar1p1_slim_driver = {
1321 .driver = {
1322 .name = "sitar1p1-slim",
1323 .owner = THIS_MODULE,
1324 },
1325 .probe = wcd9xxx_slim_probe,
1326 .remove = wcd9xxx_slim_remove,
1327 .id_table = sitar1p1_slimtest_id,
1328 .resume = wcd9xxx_slim_resume,
1329 .suspend = wcd9xxx_slim_suspend,
1330};
1331
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301332static const struct slim_device_id slimtest_id[] = {
1333 {"tabla-slim", 0},
1334 {}
1335};
1336
1337static struct slim_driver tabla_slim_driver = {
1338 .driver = {
1339 .name = "tabla-slim",
1340 .owner = THIS_MODULE,
1341 },
1342 .probe = wcd9xxx_slim_probe,
1343 .remove = wcd9xxx_slim_remove,
1344 .id_table = slimtest_id,
1345 .resume = wcd9xxx_slim_resume,
1346 .suspend = wcd9xxx_slim_suspend,
1347};
1348
1349static const struct slim_device_id slimtest2x_id[] = {
1350 {"tabla2x-slim", 0},
1351 {}
1352};
1353
1354static struct slim_driver tabla2x_slim_driver = {
1355 .driver = {
1356 .name = "tabla2x-slim",
1357 .owner = THIS_MODULE,
1358 },
1359 .probe = wcd9xxx_slim_probe,
1360 .remove = wcd9xxx_slim_remove,
1361 .id_table = slimtest2x_id,
1362 .resume = wcd9xxx_slim_resume,
1363 .suspend = wcd9xxx_slim_suspend,
1364};
1365
Joonwoo Parka7172112012-07-23 16:03:49 -07001366static const struct slim_device_id taiko_slimtest_id[] = {
Kiran Kandi725f8492012-08-06 13:45:16 -07001367 {"taiko-slim-pgd", 0},
Joonwoo Parka7172112012-07-23 16:03:49 -07001368 {}
1369};
1370
1371static struct slim_driver taiko_slim_driver = {
1372 .driver = {
1373 .name = "taiko-slim",
1374 .owner = THIS_MODULE,
1375 },
1376 .probe = wcd9xxx_slim_probe,
1377 .remove = wcd9xxx_slim_remove,
1378 .id_table = taiko_slimtest_id,
1379 .resume = wcd9xxx_slim_resume,
1380 .suspend = wcd9xxx_slim_suspend,
1381};
1382
Asish Bhattacharya2b709d42011-11-15 10:39:23 +05301383#define WCD9XXX_I2C_TOP_LEVEL 0
1384#define WCD9XXX_I2C_ANALOG 1
1385#define WCD9XXX_I2C_DIGITAL_1 2
1386#define WCD9XXX_I2C_DIGITAL_2 3
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301387
1388static struct i2c_device_id tabla_id_table[] = {
Asish Bhattacharya2b709d42011-11-15 10:39:23 +05301389 {"tabla top level", WCD9XXX_I2C_TOP_LEVEL},
1390 {"tabla analog", WCD9XXX_I2C_ANALOG},
1391 {"tabla digital1", WCD9XXX_I2C_DIGITAL_1},
1392 {"tabla digital2", WCD9XXX_I2C_DIGITAL_2},
1393 {}
1394};
1395MODULE_DEVICE_TABLE(i2c, tabla_id_table);
1396
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301397static struct i2c_driver tabla_i2c_driver = {
1398 .driver = {
1399 .owner = THIS_MODULE,
1400 .name = "tabla-i2c-core",
1401 },
1402 .id_table = tabla_id_table,
1403 .probe = wcd9xxx_i2c_probe,
1404 .remove = __devexit_p(wcd9xxx_i2c_remove),
1405 .resume = wcd9xxx_i2c_resume,
1406 .suspend = wcd9xxx_i2c_suspend,
1407};
1408
1409static int __init wcd9xxx_init(void)
1410{
Joonwoo Parka7172112012-07-23 16:03:49 -07001411 int ret1, ret2, ret3, ret4, ret5, ret6;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301412
1413 ret1 = slim_driver_register(&tabla_slim_driver);
1414 if (ret1 != 0)
1415 pr_err("Failed to register tabla SB driver: %d\n", ret1);
1416
1417 ret2 = slim_driver_register(&tabla2x_slim_driver);
1418 if (ret2 != 0)
1419 pr_err("Failed to register tabla2x SB driver: %d\n", ret2);
1420
1421 ret3 = i2c_add_driver(&tabla_i2c_driver);
1422 if (ret3 != 0)
1423 pr_err("failed to add the I2C driver\n");
1424
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301425 ret4 = slim_driver_register(&sitar_slim_driver);
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001426 if (ret4 != 0)
Asish Bhattacharyab86c3472012-02-15 08:31:52 +05301427 pr_err("Failed to register sitar SB driver: %d\n", ret4);
1428
Bhalchandra Gajare83c81f62012-05-18 16:09:05 -07001429 ret5 = slim_driver_register(&sitar1p1_slim_driver);
1430 if (ret5 != 0)
1431 pr_err("Failed to register sitar SB driver: %d\n", ret5);
1432
Joonwoo Parka7172112012-07-23 16:03:49 -07001433 ret6 = slim_driver_register(&taiko_slim_driver);
1434 if (ret6 != 0)
1435 pr_err("Failed to register taiko SB driver: %d\n", ret6);
1436
1437 return (ret1 && ret2 && ret3 && ret4 && ret5 && ret6) ? -1 : 0;
Asish Bhattacharyab1aeae22012-02-15 08:29:28 +05301438}
1439module_init(wcd9xxx_init);
1440
1441static void __exit wcd9xxx_exit(void)
1442{
1443}
1444module_exit(wcd9xxx_exit);
1445
1446MODULE_DESCRIPTION("Codec core driver");
1447MODULE_VERSION("1.0");
1448MODULE_LICENSE("GPL v2");