Hi again.
I've attached a copy of the cs53l32a module code.
To compile this module requires EXP4 to be set to 0xF4 in the file i2c-id.h.
This file is located at:
/usr/src/linux-2.6.8.1-12mdk/include/linux/i2c-id.h
on my machine. Perhaps someone who knows a bit more about writing modules can
write a patch for this module so it does not require this change.
Best Regards
Trev
/*
* cs53l32a (avc-2010 and avc-2410) i2c driver, well sort of, just initialises the device
* Martin Vaughan
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/videodev.h>
#include <linux/init.h>
#include <linux/smp_lock.h>
#include <asm/pgtable.h>
#include <asm/semaphore.h>
/* If you don't want to patch to v4l2, grab a copy of
* * videodev2.h and put it in the same dir as this file */
#ifndef HAVE_V4L2
#define HAVE_V4L2 1
#endif
#ifndef I2C_DRIVERID_CS53L32A
// Using temporary hack for missing I2C driver-ID for cs53l32a
#define I2C_DRIVERID_CS53L32A I2C_DRIVERID_EXP4
#endif
#ifdef INIT_SIGHAND
#define SIGMASK_LOCK(current) (&(current)->sighand->siglock)
#else
#define SIGMASK_LOCK(current) (&(current)->sigmask_lock)
#endif
static int cs53l32a_attach(struct i2c_adapter *adapter);
static int cs53l32a_detach(struct i2c_client *client);
static int cs53l32a_command(struct i2c_client *client, unsigned int cmd, void *arg);
/* Addresses to scan */
static unsigned short normal_i2c[] = {I2C_CLIENT_END};
static unsigned short normal_i2c_range[] = {0x11,0x11,I2C_CLIENT_END};
I2C_CLIENT_INSMOD;
static int cs53l32a_i2c_id = 0;
MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
MODULE_AUTHOR("Martin Vaughan");
MODULE_LICENSE("GPL");
static struct i2c_driver driver = {
.name = "i2c cs53l32a driver",
.id = I2C_DRIVERID_CS53L32A,
.flags = I2C_DF_NOTIFY,
.attach_adapter = cs53l32a_attach,
.detach_client = cs53l32a_detach,
.command = cs53l32a_command,
.owner = THIS_MODULE
};
static inline int cs53l32a_write (struct i2c_client *client, u8 reg, u8 value)
{
return i2c_smbus_write_byte_data(client, reg, value);
}
static inline int cs53l32a_read (struct i2c_client *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}
static int
cs53l32a_detect_client (struct i2c_adapter *adapter,
int address,
#ifndef LINUX26
unsigned short flags,
#endif
int kind)
{
struct i2c_client *client;
printk(KERN_INFO "detecting cs53l32a client on address 0x%x\n",
address << 1);
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
{
printk(KERN_INFO "No Functionality \n");
return 0;
}
client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (client == 0)
{printk(KERN_INFO "No kmalloc \n");
return -ENOMEM;}
memset(client, 0, sizeof(struct i2c_client));
client->addr = address;
client->adapter = adapter;
client->driver = &driver;
client->flags = I2C_CLIENT_ALLOW_USE;
client->id = cs53l32a_i2c_id++;
printk(KERN_INFO "Read Reg 1 %02x \n", cs53l32a_read(client, 1));
printk(KERN_INFO "Read Reg 2 %02x \n", cs53l32a_read(client, 2));
printk(KERN_INFO "Read Reg 3 %02x \n", cs53l32a_read(client, 3));
printk(KERN_INFO "Read Reg 4 %02x \n", cs53l32a_read(client, 4));
printk(KERN_INFO "Read Reg 5 %02x \n", cs53l32a_read(client, 5));
printk(KERN_INFO "Read Reg 6 %02x \n", cs53l32a_read(client, 6));
printk(KERN_INFO "Read Reg 7 %02x \n\n", cs53l32a_read(client, 7));
// Set cs53l32a internal register for Adaptec 2010/2410 setup
cs53l32a_write (client, 0x01, (u8)0x21);
cs53l32a_write (client, 0x02, (u8)0x29);
cs53l32a_write (client, 0x03, (u8)0x30);
cs53l32a_write (client, 0x04, (u8)0x00);
cs53l32a_write (client, 0x05, (u8)0x00);
cs53l32a_write (client, 0x06, (u8)0x00);
cs53l32a_write (client, 0x07, (u8)0x00);
// Display results, should be 0x21,0x29,0x30,0x00,0x00,0x00,0x00
printk(KERN_INFO "Read Reg 1 %02x \n", cs53l32a_read(client, 1));
printk(KERN_INFO "Read Reg 2 %02x \n", cs53l32a_read(client, 2));
printk(KERN_INFO "Read Reg 3 %02x \n", cs53l32a_read(client, 3));
printk(KERN_INFO "Read Reg 4 %02x \n", cs53l32a_read(client, 4));
printk(KERN_INFO "Read Reg 5 %02x \n", cs53l32a_read(client, 5));
printk(KERN_INFO "Read Reg 6 %02x \n", cs53l32a_read(client, 6));
printk(KERN_INFO "Read Reg 7 %02x \n\n", cs53l32a_read(client, 7));
i2c_attach_client(client);
return 0;
}
static int cs53l32a_attach(struct i2c_adapter *adapter)
{
printk(KERN_INFO "starting probe for adapter %s (0x%x)\n",
adapter->name, adapter->id);
return i2c_probe(adapter, &addr_data, &cs53l32a_detect_client); return 0;
}
static int cs53l32a_detach(struct i2c_client *client)
{
i2c_detach_client(client);
#ifndef LINUX26
MOD_DEC_USE_COUNT;
#endif
return 0;
}
static int cs53l32a_command(struct i2c_client *client, unsigned int cmd, void *arg)
{
return 0;
}
/* ----------------------------------------------------------------------- */
static int cs53l32a_init_module(void)
{
i2c_add_driver(&driver);
return 0;
}
static void cs53l32a_cleanup_module(void)
{
i2c_del_driver(&driver);
}
module_init(cs53l32a_init_module);
module_exit(cs53l32a_cleanup_module);