Commit ba60ea4d authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] v4l: mxb driver and i2c helper cleanup

The attached patch cleans up my Video4Linux "MXB" driver and the i2c helper
chipset drivers used by that cards.

I ran Lindent on the files and fixed some other coding style violations,
which makes the patch rather big.

But besides the MODULE_PARM => module_param there have been no crucial
changes.

- [V4L] mxb: replace MODULE_PARM with module_param

- [V4L] saa7111: replace MODULE_PARM with module_param

- [V4L] tda9840: replace MODULE_PARM with module_param, re-indent code
  with Lindent, remove unnecessary header includes, code simplification

- [V4L] tea6415c: replace MODULE_PARM with module_param, re-indent code
  with Lindent, remove unnecessary header includes, code simplification

- [V4L] tea6420: replace MODULE_PARM with module_param, re-indent code
  with Lindent, remove unnecessary header includes, code simplification
Signed-off-by: default avatarMichael Hunold <hunold@linuxtv.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0da0570b
/* /*
mxb.c - v4l2 driver for the Multimedia eXtension Board mxb - v4l2 driver for the Multimedia eXtension Board
Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
...@@ -43,12 +43,12 @@ static int mxb_num = 0; ...@@ -43,12 +43,12 @@ static int mxb_num = 0;
in verden (lower saxony, germany) 4148 is a in verden (lower saxony, germany) 4148 is a
channel called "phoenix" */ channel called "phoenix" */
static int freq = 4148; static int freq = 4148;
MODULE_PARM(freq,"i"); module_param(freq, int, 0644);
MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup"); MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
static int debug = 0; static int debug = 0;
MODULE_PARM(debug,"i"); module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "debug verbosity"); MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
#define MXB_INPUTS 4 #define MXB_INPUTS 4
enum { TUNER, AUX1, AUX3, AUX3_YC }; enum { TUNER, AUX1, AUX3, AUX3_YC };
......
...@@ -60,7 +60,7 @@ MODULE_LICENSE("GPL"); ...@@ -60,7 +60,7 @@ MODULE_LICENSE("GPL");
#include <linux/video_decoder.h> #include <linux/video_decoder.h>
static int debug = 0; static int debug = 0;
MODULE_PARM(debug, "i"); module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)"); MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define dprintk(num, format, args...) \ #define dprintk(num, format, args...) \
......
/* /*
tda9840.h - i2c-driver for the tda9840 by SGS Thomson tda9840 - i2c-driver for the tda9840 by SGS Thomson
Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
For detailed informations download the specifications directly For detailed informations download the specifications directly
from SGS Thomson at http://www.st.com from SGS Thomson at http://www.st.com
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
...@@ -22,21 +22,19 @@ ...@@ -22,21 +22,19 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/ioctl.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/init.h>
#include "tda9840.h" #include "tda9840.h"
static int debug = 0; /* insmod parameter */ static int debug = 0; /* insmod parameter */
MODULE_PARM(debug,"i"); module_param(debug, int, 0644);
#define dprintk if (debug) printk MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
#define dprintk(args...) \
do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
#define SWITCH 0x00 #define SWITCH 0x00
#define LEVEL_ADJUST 0x02 #define LEVEL_ADJUST 0x02
...@@ -44,168 +42,146 @@ MODULE_PARM(debug,"i"); ...@@ -44,168 +42,146 @@ MODULE_PARM(debug,"i");
#define TEST 0x04 #define TEST 0x04
/* addresses to scan, found only at 0x42 (7-Bit) */ /* addresses to scan, found only at 0x42 (7-Bit) */
static unsigned short normal_i2c[] = {I2C_TDA9840, I2C_CLIENT_END}; static unsigned short normal_i2c[] = { I2C_TDA9840, I2C_CLIENT_END };
static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
/* magic definition of all other variables and things */ /* magic definition of all other variables and things */
I2C_CLIENT_INSMOD; I2C_CLIENT_INSMOD;
static struct i2c_driver driver;
static struct i2c_client client_template;
/* unique ID allocation */ /* unique ID allocation */
static int tda9840_id = 0; static int tda9840_id = 0;
static struct i2c_driver driver; static int command(struct i2c_client *client, unsigned int cmd, void *arg)
static int tda9840_command(struct i2c_client *client, unsigned int cmd, void* arg)
{ {
int result = 0; int result;
int byte = *(int *)arg;
switch (cmd) { switch (cmd) {
case TDA9840_SWITCH: case TDA9840_SWITCH:
{
int byte = *(int*)arg; dprintk("TDA9840_SWITCH: 0x%02x\n", byte);
dprintk("tda9840.o: TDA9840_SWITCH: 0x%02x\n",byte); if (byte != TDA9840_SET_MONO
&& byte != TDA9840_SET_MUTE
if ( byte != TDA9840_SET_MONO && byte != TDA9840_SET_STEREO
&& byte != TDA9840_SET_MUTE && byte != TDA9840_SET_LANG1
&& byte != TDA9840_SET_STEREO && byte != TDA9840_SET_LANG2
&& byte != TDA9840_SET_LANG1 && byte != TDA9840_SET_BOTH
&& byte != TDA9840_SET_LANG2 && byte != TDA9840_SET_BOTH_R
&& byte != TDA9840_SET_BOTH && byte != TDA9840_SET_EXTERNAL) {
&& byte != TDA9840_SET_BOTH_R return -EINVAL;
&& byte != TDA9840_SET_EXTERNAL ) {
return -EINVAL;
}
if ( 0 != (result = i2c_smbus_write_byte_data(client, SWITCH, byte))) {
printk("tda9840.o: TDA9840_SWITCH error.\n");
return -EFAULT;
}
return 0;
} }
case TDA9840_LEVEL_ADJUST: result = i2c_smbus_write_byte_data(client, SWITCH, byte);
{ if (result)
int byte = *(int*)arg; dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
break;
dprintk("tda9840.o: TDA9840_LEVEL_ADJUST: %d\n",byte);
/* check for correct range */
if ( byte > 25 || byte < -20 )
return -EINVAL;
/* calculate actual value to set, see specs, page 18 */
byte /= 5;
if ( 0 < byte )
byte += 0x8;
else
byte = -byte;
if ( 0 != (result = i2c_smbus_write_byte_data(client, LEVEL_ADJUST, byte))) {
printk("tda9840.o: TDA9840_LEVEL_ADJUST error.\n");
return -EFAULT;
}
return 0;
}
case TDA9840_STEREO_ADJUST: case TDA9840_LEVEL_ADJUST:
{
int byte = *(int*)arg;
dprintk("tda9840.o: TDA9840_STEREO_ADJUST: %d\n",byte);
/* check for correct range */
if ( byte > 25 || byte < -24 )
return -EINVAL;
/* calculate actual value to set */
byte /= 5;
if ( 0 < byte )
byte += 0x20;
else
byte = -byte;
if ( 0 != (result = i2c_smbus_write_byte_data(client, STEREO_ADJUST, byte))) {
printk("tda9840.o: TDA9840_STEREO_ADJUST error.\n");
return -EFAULT;
}
return 0;
}
case TDA9840_DETECT: dprintk("TDA9840_LEVEL_ADJUST: %d\n", byte);
{
int byte = 0x0;
if ( -1 == (byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST))) { /* check for correct range */
printk("tda9840.o: TDA9840_DETECT error while reading.\n"); if (byte > 25 || byte < -20)
return -EFAULT; return -EINVAL;
}
if( 0 != (byte & 0x80)) { /* calculate actual value to set, see specs, page 18 */
dprintk("tda9840.o: TDA9840_DETECT, register contents invalid.\n"); byte /= 5;
return -EFAULT; if (0 < byte)
} byte += 0x8;
else
byte = -byte;
dprintk("tda9840.o: TDA9840_DETECT, result: 0x%02x (original byte)\n",byte); result = i2c_smbus_write_byte_data(client, LEVEL_ADJUST, byte);
if (result)
dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
break;
return ((byte & 0x60) >> 5); case TDA9840_STEREO_ADJUST:
}
dprintk("TDA9840_STEREO_ADJUST: %d\n", byte);
case TDA9840_TEST: /* check for correct range */
{ if (byte > 25 || byte < -24)
int byte = *(int*)arg; return -EINVAL;
dprintk("tda9840.o: TDA9840_TEST: 0x%02x\n",byte); /* calculate actual value to set */
byte /= 5;
if (0 < byte)
byte += 0x20;
else
byte = -byte;
/* mask out irrelevant bits */ result = i2c_smbus_write_byte_data(client, STEREO_ADJUST, byte);
byte &= 0x3; if (result)
dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
break;
if ( 0 != (result = i2c_smbus_write_byte_data(client, TEST, byte))) { case TDA9840_DETECT:
printk("tda9840.o: TDA9840_TEST error.\n");
return -EFAULT; byte = i2c_smbus_read_byte_data(client, STEREO_ADJUST);
} if (byte == -1) {
dprintk("i2c_smbus_read_byte_data() failed\n");
return 0; return -EIO;
} }
default: if (0 != (byte & 0x80)) {
return -ENOIOCTLCMD; dprintk("TDA9840_DETECT: register contents invalid\n");
return -EINVAL;
}
dprintk("TDA9840_DETECT: byte: 0x%02x\n", byte);
return ((byte & 0x60) >> 5);
case TDA9840_TEST:
dprintk("TDA9840_TEST: 0x%02x\n", byte);
/* mask out irrelevant bits */
byte &= 0x3;
result = i2c_smbus_write_byte_data(client, TEST, byte);
if (result)
dprintk("i2c_smbus_write_byte() failed, ret:%d\n", result);
break;
default:
return -ENOIOCTLCMD;
} }
if (result)
return -EIO;
return 0; return 0;
} }
static int tda9840_detect(struct i2c_adapter *adapter, int address, int kind) static int detect(struct i2c_adapter *adapter, int address, int kind)
{ {
struct i2c_client *client; struct i2c_client *client;
int result = 0; int result = 0;
int byte = 0x0; int byte = 0x0;
/* let's see whether this adapter can support what we need */ /* let's see whether this adapter can support what we need */
if ( 0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA|I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { if (0 == i2c_check_functionality(adapter,
I2C_FUNC_SMBUS_READ_BYTE_DATA |
I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) {
return 0; return 0;
} }
/* allocate memory for client structure */ /* allocate memory for client structure */
client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (0 == client) { if (0 == client) {
printk("tda9840.o: not enough kernel memory.\n"); printk("not enough kernel memory\n");
return -ENOMEM; return -ENOMEM;
} }
memset(client, 0, sizeof(struct i2c_client));
/* fill client structure */ /* fill client structure */
sprintf(client->name,"tda9840 (0x%02x)", address); memcpy(client, &client_template, sizeof(struct i2c_client));
client->id = tda9840_id++; client->id = tda9840_id++;
client->flags = 0;
client->addr = address; client->addr = address;
client->adapter = adapter; client->adapter = adapter;
client->driver = &driver;
i2c_set_clientdata(client, NULL);
/* tell the i2c layer a new client has arrived */ /* tell the i2c layer a new client has arrived */
if (0 != (result = i2c_attach_client(client))) { if (0 != (result = i2c_attach_client(client))) {
...@@ -215,71 +191,64 @@ static int tda9840_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -215,71 +191,64 @@ static int tda9840_detect(struct i2c_adapter *adapter, int address, int kind)
/* set initial values for level & stereo - adjustment, mode */ /* set initial values for level & stereo - adjustment, mode */
byte = 0; byte = 0;
if ( 0 != (result = tda9840_command(client, TDA9840_LEVEL_ADJUST, &byte))) { result = command(client, TDA9840_LEVEL_ADJUST, &byte);
printk("tda9840.o: could not initialize ic #1. continuing anyway. (result:%d)\n",result); result += command(client, TDA9840_STEREO_ADJUST, &byte);
}
if ( 0 != (result = tda9840_command(client, TDA9840_STEREO_ADJUST, &byte))) {
printk("tda9840.o: could not initialize ic #2. continuing anyway. (result:%d)\n",result);
}
byte = TDA9840_SET_MONO; byte = TDA9840_SET_MONO;
if ( 0 != (result = tda9840_command(client, TDA9840_SWITCH, &byte))) { result = command(client, TDA9840_SWITCH, &byte);
printk("tda9840.o: could not initialize ic #3. continuing anyway. (result:%d)\n",result); if (result) {
} dprintk("could not initialize tda9840\n");
return -ENODEV;
printk("tda9840.o: detected @ 0x%02x on adapter %s\n",2*address,&client->adapter->name[0]); }
printk("tda9840: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]);
return 0; return 0;
} }
static int tda9840_attach(struct i2c_adapter *adapter) static int attach(struct i2c_adapter *adapter)
{ {
/* let's see whether this is a know adapter we can attach to */ /* let's see whether this is a know adapter we can attach to */
if( adapter->id != I2C_ALGO_SAA7146 ) { if (adapter->id != I2C_ALGO_SAA7146) {
dprintk("tda9840.o: refusing to probe on unknown adapter [name='%s',id=0x%x]\n",adapter->name,adapter->id); dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id);
return -ENODEV; return -ENODEV;
} }
return i2c_probe(adapter,&addr_data,&tda9840_detect); return i2c_probe(adapter, &addr_data, &detect);
} }
static int tda9840_detach(struct i2c_client *client) static int detach(struct i2c_client *client)
{ {
int err = 0; int ret = i2c_detach_client(client);
if ( 0 != (err = i2c_detach_client(client))) {
printk("tda9840.o: Client deregistration failed, client not detached.\n");
return err;
}
kfree(client); kfree(client);
return ret;
return 0;
} }
static struct i2c_driver driver = { static struct i2c_driver driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "tda9840 driver", .name = "tda9840",
.id = I2C_DRIVERID_TDA9840, .id = I2C_DRIVERID_TDA9840,
.flags = I2C_DF_NOTIFY, .flags = I2C_DF_NOTIFY,
.attach_adapter = tda9840_attach, .attach_adapter = attach,
.detach_client = tda9840_detach, .detach_client = detach,
.command = tda9840_command, .command = command,
};
static struct i2c_client client_template = {
I2C_DEVNAME("tda9840"),
.driver = &driver,
}; };
static int __init tda9840_init_module(void) static int __init this_module_init(void)
{ {
return i2c_add_driver(&driver); return i2c_add_driver(&driver);
} }
static void __exit tda9840_cleanup_module(void) static void __exit this_module_exit(void)
{ {
i2c_del_driver(&driver); i2c_del_driver(&driver);
} }
module_init(tda9840_init_module); module_init(this_module_init);
module_exit(tda9840_cleanup_module); module_exit(this_module_exit);
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("tda9840 driver"); MODULE_DESCRIPTION("tda9840 driver");
......
/* /*
tea6415c.h - i2c-driver for the tea6415c by SGS Thomson tea6415c - i2c-driver for the tea6415c by SGS Thomson
Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
with 8 inputs and 6 outputs. with 8 inputs and 6 outputs.
It is cascadable, i.e. it can be found at the addresses It is cascadable, i.e. it can be found at the addresses
0x86 and 0x06 on the i2c-bus. 0x86 and 0x06 on the i2c-bus.
For detailed informations download the specifications directly For detailed informations download the specifications directly
from SGS Thomson at http://www.st.com from SGS Thomson at http://www.st.com
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License vs published by it under the terms of the GNU General Public License vs published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
...@@ -24,61 +24,58 @@ ...@@ -24,61 +24,58 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mvss Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/ioctl.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/init.h>
#include "tea6415c.h" #include "tea6415c.h"
static int debug = 0; /* insmod parameter */ static int debug = 0; /* insmod parameter */
MODULE_PARM(debug,"i"); module_param(debug, int, 0644);
#define dprintk if (debug) printk MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
#define dprintk(args...) \
do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
#define TEA6415C_NUM_INPUTS 8 #define TEA6415C_NUM_INPUTS 8
#define TEA6415C_NUM_OUTPUTS 6 #define TEA6415C_NUM_OUTPUTS 6
/* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */ /* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */
static unsigned short normal_i2c[] = {I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END}; static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END };
static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
/* magic definition of all other variables and things */ /* magic definition of all other variables and things */
I2C_CLIENT_INSMOD; I2C_CLIENT_INSMOD;
static struct i2c_driver driver; static struct i2c_driver driver;
static struct i2c_client client_template;
/* unique ID allocation */ /* unique ID allocation */
static int tea6415c_id = 0; static int tea6415c_id = 0;
/* this function is called by i2c_probe */ /* this function is called by i2c_probe */
static int tea6415c_detect(struct i2c_adapter *adapter, int address, int kind) static int detect(struct i2c_adapter *adapter, int address, int kind)
{ {
struct i2c_client *client = NULL; struct i2c_client *client = NULL;
int err = 0; int err = 0;
/* let's see whether this adapter can support what we need */ /* let's see whether this adapter can support what we need */
if ( 0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) {
return 0; return 0;
} }
/* allocate memory for client structure */ /* allocate memory for client structure */
client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (0 == client) { if (0 == client) {
return -ENOMEM; return -ENOMEM;
} }
memset(client, 0, sizeof(struct i2c_client));
/* fill client structure */ /* fill client structure */
sprintf(client->name,"tea6415c (0x%02x)", address); memcpy(client, &client_template, sizeof(struct i2c_client));
client->id = tea6415c_id++; client->id = tea6415c_id++;
client->flags = 0;
client->addr = address; client->addr = address;
client->adapter = adapter; client->adapter = adapter;
client->driver = &driver;
/* tell the i2c layer a new client has arrived */ /* tell the i2c layer a new client has arrived */
if (0 != (err = i2c_attach_client(client))) { if (0 != (err = i2c_attach_client(client))) {
...@@ -86,151 +83,145 @@ static int tea6415c_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -86,151 +83,145 @@ static int tea6415c_detect(struct i2c_adapter *adapter, int address, int kind)
return err; return err;
} }
printk("tea6415c.o: detected @ 0x%02x on adapter %s\n",2*address,&client->adapter->name[0]); printk("tea6415c: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]);
return 0; return 0;
} }
static int tea6415c_attach(struct i2c_adapter *adapter) static int attach(struct i2c_adapter *adapter)
{ {
/* let's see whether this is a know adapter we can attach to */ /* let's see whether this is a know adapter we can attach to */
if( adapter->id != I2C_ALGO_SAA7146 ) { if (adapter->id != I2C_ALGO_SAA7146) {
dprintk("tea6415c.o: refusing to probe on unknown adapter [name='%s',id=0x%x]\n",adapter->name,adapter->id); dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id);
return -ENODEV; return -ENODEV;
} }
return i2c_probe(adapter,&addr_data,&tea6415c_detect); return i2c_probe(adapter, &addr_data, &detect);
} }
static int tea6415c_detach(struct i2c_client *client) static int detach(struct i2c_client *client)
{ {
int err = 0; int ret = i2c_detach_client(client);
if ( 0 != (err = i2c_detach_client(client))) {
printk("tea6415c.o: Client deregistration failed, client not detached.\n");
return err;
}
kfree(client); kfree(client);
return ret;
return 0;
} }
/* makes a connection between the input-pin 'i' and the output-pin 'o' /* makes a connection between the input-pin 'i' and the output-pin 'o'
for the tea6415c-client 'client' */ for the tea6415c-client 'client' */
static int tea6415c_switch(struct i2c_client *client, int i, int o) static int switch_matrix(struct i2c_client *client, int i, int o)
{ {
u8 byte = 0; u8 byte = 0;
int ret;
dprintk("tea6415c.o: tea6415c_switch: adr:0x%02x, i:%d, o:%d\n", client->addr, i, o); dprintk("adr:0x%02x, i:%d, o:%d\n", client->addr, i, o);
/* check if the pins are valid */ /* check if the pins are valid */
if ( 0 == (( 1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i ) && if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i)
(18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o ))) && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o)))
return -1; return -1;
/* to understand this, have a look at the tea6415c-specs (p.5) */ /* to understand this, have a look at the tea6415c-specs (p.5) */
switch(o) { switch (o) {
case 18: case 18:
byte = 0x00; byte = 0x00;
break; break;
case 14: case 14:
byte = 0x20; byte = 0x20;
break; break;
case 16: case 16:
byte = 0x10; byte = 0x10;
break; break;
case 17: case 17:
byte = 0x08; byte = 0x08;
break; break;
case 15: case 15:
byte = 0x18; byte = 0x18;
break; break;
case 13: case 13:
byte = 0x28; byte = 0x28;
break; break;
}; };
switch(i) { switch (i) {
case 5: case 5:
byte |= 0x00; byte |= 0x00;
break; break;
case 8: case 8:
byte |= 0x04; byte |= 0x04;
break; break;
case 3: case 3:
byte |= 0x02; byte |= 0x02;
break; break;
case 20: case 20:
byte |= 0x06; byte |= 0x06;
break; break;
case 6: case 6:
byte |= 0x01; byte |= 0x01;
break; break;
case 10: case 10:
byte |= 0x05; byte |= 0x05;
break; break;
case 1: case 1:
byte |= 0x03; byte |= 0x03;
break; break;
case 11: case 11:
byte |= 0x07; byte |= 0x07;
break; break;
}; };
if ( 0 != i2c_smbus_write_byte(client,byte)) { ret = i2c_smbus_write_byte(client, byte);
dprintk("tea6415c.o: tea6415c_switch: could not write to tea6415c\n"); if (ret) {
return -1; dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret);
return -EIO;
} }
return 0; return ret;
} }
static int tea6415c_command(struct i2c_client *client, unsigned int cmd, void* arg) static int command(struct i2c_client *client, unsigned int cmd, void *arg)
{ {
struct tea6415c_multiplex *v = (struct tea6415c_multiplex*)arg; struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg;
int result = 0; int result = 0;
switch (cmd) { switch (cmd) {
case TEA6415C_SWITCH: { case TEA6415C_SWITCH:
result = tea6415c_switch(client,v->in,v->out); result = switch_matrix(client, v->in, v->out);
break; break;
} default:
default: { return -ENOIOCTLCMD;
return -ENOIOCTLCMD;
}
} }
if ( 0 != result ) return result;
return result;
return 0;
} }
static struct i2c_driver driver = { static struct i2c_driver driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "tea6415c driver", .name = "tea6415c",
.id = I2C_DRIVERID_TEA6415C, .id = I2C_DRIVERID_TEA6415C,
.flags = I2C_DF_NOTIFY, .flags = I2C_DF_NOTIFY,
.attach_adapter = tea6415c_attach, .attach_adapter = attach,
.detach_client = tea6415c_detach, .detach_client = detach,
.command = tea6415c_command, .command = command,
};
static struct i2c_client client_template = {
I2C_DEVNAME("tea6415c"),
.driver = &driver,
}; };
static int __init tea6415c_init_module(void) static int __init this_module_init(void)
{ {
return i2c_add_driver(&driver); return i2c_add_driver(&driver);
} }
static void __exit tea6415c_cleanup_module(void) static void __exit this_module_exit(void)
{ {
i2c_del_driver(&driver); i2c_del_driver(&driver);
} }
module_init(tea6415c_init_module); module_init(this_module_init);
module_exit(tea6415c_cleanup_module); module_exit(this_module_exit);
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("tea6415c driver"); MODULE_DESCRIPTION("tea6415c driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
/* /*
tea6420.o - i2c-driver for the tea6420 by SGS Thomson tea6420 - i2c-driver for the tea6420 by SGS Thomson
Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de> Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>
...@@ -7,10 +7,10 @@ ...@@ -7,10 +7,10 @@
4 stereo outputs and gain control for each output. 4 stereo outputs and gain control for each output.
It is cascadable, i.e. it can be found at the adresses 0x98 It is cascadable, i.e. it can be found at the adresses 0x98
and 0x9a on the i2c-bus. and 0x9a on the i2c-bus.
For detailed informations download the specifications directly For detailed informations download the specifications directly
from SGS Thomson at http://www.st.com from SGS Thomson at http://www.st.com
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
...@@ -24,30 +24,29 @@ ...@@ -24,30 +24,29 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/version.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kernel.h> #include <linux/ioctl.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/init.h>
#include "tea6420.h" #include "tea6420.h"
static int debug = 0; /* insmod parameter */ static int debug = 0; /* insmod parameter */
MODULE_PARM(debug,"i"); module_param(debug, int, 0644);
#define dprintk if (debug) printk MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
#define dprintk(args...) \
do { if (debug) { printk("%s: %s()[%d]: ",__stringify(KBUILD_MODNAME), __FUNCTION__, __LINE__); printk(args); } } while (0)
/* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */ /* addresses to scan, found only at 0x4c and/or 0x4d (7-Bit) */
static unsigned short normal_i2c[] = {I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END}; static unsigned short normal_i2c[] = { I2C_TEA6420_1, I2C_TEA6420_2, I2C_CLIENT_END };
static unsigned short normal_i2c_range[] = {I2C_CLIENT_END}; static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
/* magic definition of all other variables and things */ /* magic definition of all other variables and things */
I2C_CLIENT_INSMOD; I2C_CLIENT_INSMOD;
static struct i2c_driver driver; static struct i2c_driver driver;
static struct i2c_client client_template;
/* unique ID allocation */ /* unique ID allocation */
static int tea6420_id = 0; static int tea6420_id = 0;
...@@ -56,39 +55,37 @@ static int tea6420_id = 0; ...@@ -56,39 +55,37 @@ static int tea6420_id = 0;
with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */ with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */
static int tea6420_switch(struct i2c_client *client, int i, int o, int g) static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
{ {
u8 byte = 0; u8 byte = 0;
int ret;
int result = 0;
dprintk("adr:0x%02x, i:%d, o:%d, g:%d\n", client->addr, i, o, g);
dprintk("tea6420.o: tea6420_switch: adr:0x%02x, i:%d, o:%d, g:%d\n",client->addr,i,o,g);
/* check if the paramters are valid */ /* check if the paramters are valid */
if ( i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g%2 != 0 ) if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0)
return -1; return -1;
byte = ((o-1)<<5); byte = ((o - 1) << 5);
byte |= (i-1); byte |= (i - 1);
/* to understand this, have a look at the tea6420-specs (p.5) */ /* to understand this, have a look at the tea6420-specs (p.5) */
switch(g) { switch (g) {
case 0: case 0:
byte |= (3<<3); byte |= (3 << 3);
break; break;
case 2: case 2:
byte |= (2<<3); byte |= (2 << 3);
break; break;
case 4: case 4:
byte |= (1<<3); byte |= (1 << 3);
break; break;
case 6: case 6:
break; break;
} }
/* fixme?: 1 != ... => 0 != */ ret = i2c_smbus_write_byte(client, byte);
if ( 0 != (result = i2c_smbus_write_byte(client,byte))) { if (ret) {
printk("tea6402:%d\n",result); dprintk("i2c_smbus_write_byte() failed, ret:%d\n", ret);
dprintk(KERN_ERR "tea6420.o: could not switch, result:%d\n",result); return -EIO;
return -EFAULT;
} }
return 0; return 0;
...@@ -97,29 +94,26 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g) ...@@ -97,29 +94,26 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
/* this function is called by i2c_probe */ /* this function is called by i2c_probe */
static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind)
{ {
struct i2c_client *client; struct i2c_client *client;
int err = 0, i = 0; int err = 0, i = 0;
/* let's see whether this adapter can support what we need */ /* let's see whether this adapter can support what we need */
if ( 0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) { if (0 == i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE)) {
return 0; return 0;
} }
/* allocate memory for client structure */ /* allocate memory for client structure */
client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
if (0 == client) { if (0 == client) {
return -ENOMEM; return -ENOMEM;
} }
memset(client, 0x0, sizeof(struct i2c_client)); memset(client, 0x0, sizeof(struct i2c_client));
/* fill client structure */ /* fill client structure */
sprintf(client->name,"tea6420 (0x%02x)", address); memcpy(client, &client_template, sizeof(struct i2c_client));
client->id = tea6420_id++; client->id = tea6420_id++;
client->flags = 0;
client->addr = address; client->addr = address;
client->adapter = adapter; client->adapter = adapter;
client->driver = &driver;
i2c_set_clientdata(client, NULL);
/* tell the i2c layer a new client has arrived */ /* tell the i2c layer a new client has arrived */
if (0 != (err = i2c_attach_client(client))) { if (0 != (err = i2c_attach_client(client))) {
...@@ -129,86 +123,81 @@ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind) ...@@ -129,86 +123,81 @@ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind)
/* set initial values: set "mute"-input to all outputs at gain 0 */ /* set initial values: set "mute"-input to all outputs at gain 0 */
err = 0; err = 0;
for(i = 1; i < 5; i++) { for (i = 1; i < 5; i++) {
err += tea6420_switch(client, 6, i, 0); err += tea6420_switch(client, 6, i, 0);
} }
if( 0 != err) { if (err) {
printk("tea6420.o: could not initialize chipset. continuing anyway.\n"); dprintk("could not initialize tea6420\n");
kfree(client);
return -ENODEV;
} }
printk("tea6420.o: detected @ 0x%02x on adapter %s\n",2*address,&client->adapter->name[0]); printk("tea6420: detected @ 0x%02x on adapter %s\n", address, &client->adapter->name[0]);
return 0; return 0;
} }
static int tea6420_attach(struct i2c_adapter *adapter) static int attach(struct i2c_adapter *adapter)
{ {
/* let's see whether this is a know adapter we can attach to */ /* let's see whether this is a know adapter we can attach to */
if( adapter->id != I2C_ALGO_SAA7146 ) { if (adapter->id != I2C_ALGO_SAA7146) {
dprintk("tea6420.o: refusing to probe on unknown adapter [name='%s',id=0x%x]\n",adapter->name,adapter->id); dprintk("refusing to probe on unknown adapter [name='%s',id=0x%x]\n", adapter->name, adapter->id);
return -ENODEV; return -ENODEV;
} }
return i2c_probe(adapter,&addr_data,&tea6420_detect); return i2c_probe(adapter, &addr_data, &tea6420_detect);
} }
static int tea6420_detach(struct i2c_client *client) static int detach(struct i2c_client *client)
{ {
int err = 0; int ret = i2c_detach_client(client);
if ( 0 != (err = i2c_detach_client(client))) {
printk("tea6420.o: Client deregistration failed, client not detached.\n");
return err;
}
kfree(client); kfree(client);
return ret;
return 0;
} }
static int tea6420_command(struct i2c_client *client, unsigned int cmd, void* arg) static int command(struct i2c_client *client, unsigned int cmd, void *arg)
{ {
struct tea6420_multiplex *a = (struct tea6420_multiplex*)arg; struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg;
int result = 0; int result = 0;
switch (cmd) { switch (cmd) {
case TEA6420_SWITCH: { case TEA6420_SWITCH:
result = tea6420_switch(client,a->in,a->out,a->gain); result = tea6420_switch(client, a->in, a->out, a->gain);
break; break;
} default:
default: { return -ENOIOCTLCMD;
return -ENOIOCTLCMD;
}
} }
if ( 0 != result ) return result;
return result;
return 0;
} }
static struct i2c_driver driver = { static struct i2c_driver driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.name = "tea6420 driver", .name = "tea6420",
.id = I2C_DRIVERID_TEA6420, .id = I2C_DRIVERID_TEA6420,
.flags = I2C_DF_NOTIFY, .flags = I2C_DF_NOTIFY,
.attach_adapter = tea6420_attach, .attach_adapter = attach,
.detach_client = tea6420_detach, .detach_client = detach,
.command = tea6420_command, .command = command,
};
static struct i2c_client client_template = {
I2C_DEVNAME("tea6420"),
.driver = &driver,
}; };
static int __init tea6420_init_module(void) static int __init this_module_init(void)
{ {
return i2c_add_driver(&driver); return i2c_add_driver(&driver);
} }
static void __exit tea6420_cleanup_module(void) static void __exit this_module_exit(void)
{ {
i2c_del_driver(&driver); i2c_del_driver(&driver);
} }
module_init(tea6420_init_module); module_init(this_module_init);
module_exit(tea6420_cleanup_module); module_exit(this_module_exit);
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("tea6420 driver"); MODULE_DESCRIPTION("tea6420 driver");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment