2 * linux/sound/soc/codecs/AIC3262_tiload.c
5 * Copyright (C) 2010 Texas Instruments, Inc.
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.
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.
19 * Rev 0.1 Tiload support TI 16-09-2010
21 * The Tiload programming support is added to AIC3262.
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/init.h>
28 #include <linux/kernel.h>
30 #include <linux/types.h>
31 #include <linux/kdev_t.h>
32 #include <linux/cdev.h>
33 #include <linux/device.h>
35 #include <linux/delay.h>
36 #include <linux/i2c.h>
37 #include <linux/platform_device.h>
38 #include <sound/soc.h>
39 #include <sound/control.h>
40 #include <linux/switch.h>
41 #include <sound/jack.h>
42 #include <linux/irq.h>
43 #include <linux/interrupt.h>
45 #include <linux/mfd/tlv320aic3262-core.h>
46 #include "tlv320aic326x.h"
47 #include "aic326x_tiload.h"
49 /* enable debug prints in the driver */
54 #define dprintk(x...) printk(x)
61 /* Function prototypes */
62 #ifdef REG_DUMP_aic3262
63 static void aic3262_dump_page(struct i2c_client *i2c, u8 page);
67 /*extern int aic3262_change_page(struct snd_soc_codec *codec, u8 new_page);
68 extern int aic3262_change_book(struct snd_soc_codec *codec, u8 new_book);*/
69 extern int aic3262_write(struct snd_soc_codec *codec, unsigned int reg,
72 int aic3262_driver_init(struct snd_soc_codec *codec);
73 /************** Dynamic aic3262 driver, TI LOAD support ***************/
75 static struct cdev *aic3262_cdev;
76 static aic326x_reg_union aic_reg;
77 static int aic3262_major = 0; /* Dynamic allocation of Mjr No. */
78 static int aic3262_opened = 0; /* Dynamic allocation of Mjr No. */
79 static struct snd_soc_codec *aic3262_codec;
80 struct class *tiload_class;
81 static unsigned int magic_num = 0xE0;
83 /******************************** Debug section *****************************/
85 #ifdef REG_DUMP_aic3262
87 *----------------------------------------------------------------------------
88 * Function : aic3262_dump_page
89 * Purpose : Read and display one codec register page, for debugging purpose
90 *----------------------------------------------------------------------------
92 static void aic3262_dump_page(struct i2c_client *i2c, u8 page)
96 u8 test_page_array[8];
98 dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
99 // aic3262_change_page(codec, page);
103 i2c_master_send(i2c, data, 1);
104 i2c_master_recv(i2c, test_page_array, 8);
106 dprintk("\n------- aic3262 PAGE %d DUMP --------\n", page);
107 for (i = 0; i < 8; i++) {
108 printk(" [ %d ] = 0x%x\n", i, test_page_array[i]);
114 *----------------------------------------------------------------------------
115 * Function : tiload_open
117 * Purpose : open method for aic3262-tiload programming interface
118 *----------------------------------------------------------------------------
120 static int tiload_open(struct inode *in, struct file *filp)
122 dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
123 if (aic3262_opened) {
124 dprintk("%s device is already opened\n", "aic3262");
125 dprintk("%s: only one instance of driver is allowed\n",
134 *----------------------------------------------------------------------------
135 * Function : tiload_release
137 * Purpose : close method for aic3262_tilaod programming interface
138 *----------------------------------------------------------------------------
140 static int tiload_release(struct inode *in, struct file *filp)
142 dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
148 *----------------------------------------------------------------------------
149 * Function : tiload_read
151 * Purpose : read method for mini dsp programming interface
152 *----------------------------------------------------------------------------
154 static ssize_t tiload_read(struct file *file, char __user * buf,
155 size_t count, loff_t * offset)
157 static char rd_data[8];
163 struct aic3262 *control = aic3262_codec->control_data;
165 dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
167 printk("Max 128 bytes can be read\n");
171 /* copy register address from user space */
172 size = copy_from_user(®_addr, buf, 1);
174 printk("read: copy_from_user failure\n");
177 /* Send the address to device thats is to be read */
179 aic_reg.aic326x_register.offset = reg_addr;
180 size = aic3262_bulk_read(control, aic_reg.aic326x_register_int, count, rd_data);
182 if (i2c_master_send(i2c, ®_addr, 1) != 1) {
183 dprintk("Can not write register address\n");
186 size = i2c_master_recv(i2c, rd_data, count);
189 printk(KERN_ERR "read size = %d, reg_addr= %x , count = %d\n",
190 (int)size, reg_addr, (int)count);
191 for (i = 0; i < (int)size; i++) {
192 dprintk(KERN_ERR "rd_data[%d]=%x\n", i, rd_data[i]);
196 dprintk("read %d registers from the codec\n", size);
199 if (copy_to_user(buf, rd_data, size) != 0) {
200 dprintk("copy_to_user failed\n");
208 *----------------------------------------------------------------------------
209 * Function : tiload_write
211 * Purpose : write method for aic3262_tiload programming interface
212 *----------------------------------------------------------------------------
214 static ssize_t tiload_write(struct file *file, const char __user * buf,
215 size_t count, loff_t * offset)
217 static char wr_data[8];
223 struct aic3262 *control = aic3262_codec->control_data;
225 dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
226 /* copy buffer from user space */
227 if (copy_from_user(wr_data, buf, count)) {
228 printk("copy_from_user failure\n");
232 dprintk(KERN_ERR "write size = %d\n", (int)count);
233 for (i = 0; i < (int)count; i++) {
234 printk(KERN_INFO "\nwr_data[%d]=%x\n", i, wr_data[i]);
239 //change of page seen, but will only be registered
240 aic_reg.aic326x_register.page = wr_data[1];
241 return count;// trick
245 if(wr_data[0] == 127 /* && aic_reg.aic326x_register.page == 0*/)
247 //change of book seen, but will not be sent for I2C write
248 aic_reg.aic326x_register.book = wr_data[1];
249 return count; //trick
254 aic_reg.aic326x_register.offset = wr_data[0];
255 aic3262_bulk_write(control, aic_reg.aic326x_register_int, count - 1,&wr_data[1]);
258 /* if (wr_data[0] == 0) {
259 aic3262_change_page(aic3262_codec, wr_data[1]);
262 pg_no = aic3262_private->page_no;
264 if ((wr_data[0] == 127) && (pg_no == 0)) {
265 aic3262_change_book(aic3262_codec, wr_data[1]);
268 return i2c_master_send(i2c, wr_data, count);*/
272 static long tiload_ioctl(struct file *filp,
273 unsigned int cmd, unsigned long arg)
276 void __user *argp = (void __user *)arg;
277 if (_IOC_TYPE(cmd) != aic3262_IOC_MAGIC)
280 dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
282 case aic3262_IOMAGICNUM_GET:
283 num = copy_to_user(argp, &magic_num, sizeof(int));
285 case aic3262_IOMAGICNUM_SET:
286 num = copy_from_user(&magic_num, argp, sizeof(int));
292 /*********** File operations structure for aic3262-tiload programming *************/
293 static struct file_operations aic3262_fops = {
294 .owner = THIS_MODULE,
296 .release = tiload_release,
298 .write = tiload_write,
299 .unlocked_ioctl = tiload_ioctl,
303 *----------------------------------------------------------------------------
304 * Function : aic3262_driver_init
306 * Purpose : Register a char driver for dynamic aic3262-tiload programming
307 *----------------------------------------------------------------------------
309 int aic3262_driver_init(struct snd_soc_codec *codec)
313 dev_t dev = MKDEV(aic3262_major, 0);
314 dprintk("TiLoad DRIVER : %s\n", __FUNCTION__);
315 aic3262_codec = codec;
317 dprintk("allocating dynamic major number\n");
319 result = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);
321 dprintk("cannot allocate major number %d\n", aic3262_major);
325 tiload_class = class_create(THIS_MODULE, DEVICE_NAME);
326 aic3262_major = MAJOR(dev);
327 dprintk("allocated Major Number: %d\n", aic3262_major);
329 aic3262_cdev = cdev_alloc();
330 cdev_init(aic3262_cdev, &aic3262_fops);
331 aic3262_cdev->owner = THIS_MODULE;
332 aic3262_cdev->ops = &aic3262_fops;
334 aic_reg.aic326x_register.page = 0;
335 aic_reg.aic326x_register.book = 0;
337 if (cdev_add(aic3262_cdev, dev, 1) < 0) {
338 dprintk("aic3262_driver: cdev_add failed \n");
339 unregister_chrdev_region(dev, 1);
343 dprintk("Registered aic3262 TiLoad driver, Major number: %d \n",
345 //class_device_create(tiload_class, NULL, dev, NULL, DEVICE_NAME, 0);