Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c19c6c32 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6

* 'i2c-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6:
  go7007: Convert to the new i2c device binding model
parents daba0280 7400516a
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -191,8 +191,10 @@ int go7007_reset_encoder(struct go7007 *go)
/*
 * Attempt to instantiate an I2C client by ID, probably loading a module.
 */
static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr)
static int init_i2c_module(struct i2c_adapter *adapter, const char *type,
			   int id, int addr)
{
	struct i2c_board_info info;
	char *modname;

	switch (id) {
@@ -226,7 +228,11 @@ static int init_i2c_module(struct i2c_adapter *adapter, int id, int addr)
	}
	if (modname != NULL)
		request_module(modname);
	if (wis_i2c_probe_device(adapter, id, addr) == 1)

	memset(&info, 0, sizeof(struct i2c_board_info));
	info.addr = addr;
	strlcpy(info.type, type, I2C_NAME_SIZE);
	if (!i2c_new_device(adapter, &info))
		return 0;
	if (modname != NULL)
		printk(KERN_INFO
@@ -266,6 +272,7 @@ int go7007_register_encoder(struct go7007 *go)
	if (go->i2c_adapter_online) {
		for (i = 0; i < go->board_info->num_i2c_devs; ++i)
			init_i2c_module(&go->i2c_adapter,
					go->board_info->i2c_devs[i].type,
					go->board_info->i2c_devs[i].id,
					go->board_info->i2c_devs[i].addr);
		if (go->board_id == GO7007_BOARDID_ADLINK_MPG24)
+0 −83
Original line number Diff line number Diff line
@@ -31,87 +31,6 @@
#include "go7007-priv.h"
#include "wis-i2c.h"

/************** Registration interface for I2C client drivers **************/

/* Since there's no way to auto-probe the I2C devices connected to the I2C
 * bus on the go7007, we have this silly little registration system that
 * client drivers can use to register their I2C driver ID and their
 * detect_client function (the one that's normally passed to i2c_probe).
 *
 * When a new go7007 device is connected, we can look up in a board info
 * table by the USB or PCI vendor/product/revision ID to determine
 * which I2C client module to load.  The client driver module will register
 * itself here, and then we can call the registered detect_client function
 * to force-load a new client at the address listed in the board info table.
 *
 * Really the I2C subsystem should have a way to force-load I2C client
 * drivers when we have a priori knowledge of what's on the bus, especially
 * since the existing I2C auto-probe mechanism is so hokey, but we'll use
 * our own mechanism for the time being. */

struct wis_i2c_client_driver {
	unsigned int id;
	found_proc found_proc;
	struct list_head list;
};

static LIST_HEAD(i2c_client_drivers);
static DECLARE_MUTEX(i2c_client_driver_list_lock);

/* Client drivers register here by their I2C driver ID */
int wis_i2c_add_driver(unsigned int id, found_proc found_proc)
{
	struct wis_i2c_client_driver *driver;

	driver = kmalloc(sizeof(struct wis_i2c_client_driver), GFP_KERNEL);
	if (driver == NULL)
		return -ENOMEM;
	driver->id = id;
	driver->found_proc = found_proc;

	down(&i2c_client_driver_list_lock);
	list_add_tail(&driver->list, &i2c_client_drivers);
	up(&i2c_client_driver_list_lock);

	return 0;
}
EXPORT_SYMBOL(wis_i2c_add_driver);

void wis_i2c_del_driver(found_proc found_proc)
{
	struct wis_i2c_client_driver *driver, *next;

	down(&i2c_client_driver_list_lock);
	list_for_each_entry_safe(driver, next, &i2c_client_drivers, list)
		if (driver->found_proc == found_proc) {
			list_del(&driver->list);
			kfree(driver);
		}
	up(&i2c_client_driver_list_lock);
}
EXPORT_SYMBOL(wis_i2c_del_driver);

/* The main go7007 driver calls this to instantiate a client by driver
 * ID and bus address, which are both stored in the board info table */
int wis_i2c_probe_device(struct i2c_adapter *adapter,
				unsigned int id, int addr)
{
	struct wis_i2c_client_driver *driver;
	int found = 0;

	if (addr < 0 || addr > 0x7f)
		return -1;
	down(&i2c_client_driver_list_lock);
	list_for_each_entry(driver, &i2c_client_drivers, list)
		if (driver->id == id) {
			if (driver->found_proc(adapter, addr, 0) == 0)
				found = 1;
			break;
		}
	up(&i2c_client_driver_list_lock);
	return found;
}

/********************* Driver for on-board I2C adapter *********************/

/* #define GO7007_I2C_DEBUG */
@@ -287,9 +206,7 @@ static struct i2c_algorithm go7007_algo = {

static struct i2c_adapter go7007_adap_templ = {
	.owner			= THIS_MODULE,
	.class			= I2C_CLASS_TV_ANALOG,
	.name			= "WIS GO7007SB",
	.id			= I2C_ALGO_GO7007,
	.algo			= &go7007_algo,
};

+1 −0
Original line number Diff line number Diff line
@@ -87,6 +87,7 @@ struct go7007_board_info {
	int audio_main_div;
	int num_i2c_devs;
	struct {
		const char *type;
		int id;
		int addr;
	} i2c_devs[4];
+11 −3
Original line number Diff line number Diff line
@@ -91,6 +91,7 @@ static struct go7007_usb_board board_matrix_ii = {
		.num_i2c_devs	 = 1,
		.i2c_devs	 = {
			{
				.type	= "wis_saa7115",
				.id	= I2C_DRIVERID_WIS_SAA7115,
				.addr	= 0x20,
			},
@@ -127,6 +128,7 @@ static struct go7007_usb_board board_matrix_reload = {
		.num_i2c_devs	 = 1,
		.i2c_devs	 = {
			{
				.type	= "wis_saa7113",
				.id	= I2C_DRIVERID_WIS_SAA7113,
				.addr	= 0x25,
			},
@@ -164,6 +166,7 @@ static struct go7007_usb_board board_star_trek = {
		.num_i2c_devs	 = 1,
		.i2c_devs	 = {
			{
				.type	= "wis_saa7115",
				.id	= I2C_DRIVERID_WIS_SAA7115,
				.addr	= 0x20,
			},
@@ -209,14 +212,17 @@ static struct go7007_usb_board board_px_tv402u = {
		.num_i2c_devs	 = 3,
		.i2c_devs	 = {
			{
				.type	= "wis_saa7115",
				.id	= I2C_DRIVERID_WIS_SAA7115,
				.addr	= 0x20,
			},
			{
				.type	= "wis_uda1342",
				.id	= I2C_DRIVERID_WIS_UDA1342,
				.addr	= 0x1a,
			},
			{
				.type	= "wis_sony_tuner",
				.id	= I2C_DRIVERID_WIS_SONY_TUNER,
				.addr	= 0x60,
			},
@@ -264,6 +270,7 @@ static struct go7007_usb_board board_xmen = {
		.num_i2c_devs	  = 1,
		.i2c_devs	  = {
			{
				.type	= "wis_ov7640",
				.id	= I2C_DRIVERID_WIS_OV7640,
				.addr	= 0x21,
			},
@@ -296,6 +303,7 @@ static struct go7007_usb_board board_matrix_revolution = {
		.num_i2c_devs	 = 1,
		.i2c_devs	 = {
			{
				.type	= "wis_tw9903",
				.id	= I2C_DRIVERID_WIS_TW9903,
				.addr	= 0x44,
			},
@@ -385,6 +393,7 @@ static struct go7007_usb_board board_adlink_mpg24 = {
		.num_i2c_devs	 = 1,
		.i2c_devs	 = {
			{
				.type	= "wis_twTW2804",
				.id	= I2C_DRIVERID_WIS_TW2804,
				.addr	= 0x00, /* yes, really */
			},
@@ -415,8 +424,9 @@ static struct go7007_usb_board board_sensoray_2250 = {
		.num_i2c_devs	 = 1,
		.i2c_devs	 = {
			{
				.type	= "s2250_board",
				.id	= I2C_DRIVERID_S2250,
				.addr	= 0x34,
				.addr	= 0x43,
			},
		},
		.num_inputs	 = 2,
@@ -943,9 +953,7 @@ static struct i2c_algorithm go7007_usb_algo = {

static struct i2c_adapter go7007_usb_adap_templ = {
	.owner			= THIS_MODULE,
	.class			= I2C_CLASS_TV_ANALOG,
	.name			= "WIS GO7007SB EZ-USB",
	.id			= I2C_ALGO_GO7007_USB,
	.algo			= &go7007_usb_algo,
};

+30 −41
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ extern int s2250loader_init(void);
extern void s2250loader_cleanup(void);

#define TLV320_ADDRESS      0x34
#define S2250_VIDDEC        0x86
#define VPX322_ADDR_ANALOGCONTROL1	0x02
#define VPX322_ADDR_BRIGHTNESS0		0x0127
#define VPX322_ADDR_BRIGHTNESS1		0x0131
@@ -123,6 +122,7 @@ struct s2250 {
	int hue;
	int reg12b_val;
	int audio_input;
	struct i2c_client *audio;
};

/* from go7007-usb.c which is Copyright (C) 2005-2006 Micronas USA Inc.*/
@@ -452,16 +452,15 @@ static int s2250_command(struct i2c_client *client,
	{
		struct v4l2_audio *audio = arg;

		client->addr = TLV320_ADDRESS;
		switch (audio->index) {
		case 0:
			write_reg(client, 0x08, 0x02); /* Line In */
			write_reg(dec->audio, 0x08, 0x02); /* Line In */
			break;
		case 1:
			write_reg(client, 0x08, 0x04); /* Mic */
			write_reg(dec->audio, 0x08, 0x04); /* Mic */
			break;
		case 2:
			write_reg(client, 0x08, 0x05); /* Mic Boost */
			write_reg(dec->audio, 0x08, 0x05); /* Mic Boost */
			break;
		default:
			return -EINVAL;
@@ -477,31 +476,23 @@ static int s2250_command(struct i2c_client *client,
	return 0;
}

static struct i2c_driver s2250_driver;

static struct i2c_client s2250_client_templ = {
	.name		= "Sensoray 2250",
	.driver		= &s2250_driver,
};

static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind)
static int s2250_probe(struct i2c_client *client,
		       const struct i2c_device_id *id)
{
	struct i2c_client *client;
	struct i2c_client *audio;
	struct i2c_adapter *adapter = client->adapter;
	struct s2250 *dec;
	u8 *data;
	struct go7007 *go = i2c_get_adapdata(adapter);
	struct go7007_usb *usb = go->hpi_context;

	client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
	if (client == NULL)
	audio = i2c_new_dummy(adapter, TLV320_ADDRESS >> 1);
	if (audio == NULL)
		return -ENOMEM;
	memcpy(client, &s2250_client_templ,
	       sizeof(s2250_client_templ));
	client->adapter = adapter;

	dec = kmalloc(sizeof(struct s2250), GFP_KERNEL);
	if (dec == NULL) {
		kfree(client);
		i2c_unregister_device(audio);
		return -ENOMEM;
	}

@@ -510,7 +501,7 @@ static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind)
	dec->contrast = 50;
	dec->saturation = 50;
	dec->hue = 0;
	client->addr = TLV320_ADDRESS;
	dec->audio = audio;
	i2c_set_clientdata(client, dec);

	printk(KERN_DEBUG
@@ -518,28 +509,25 @@ static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind)
	       adapter->name);

	/* initialize the audio */
	client->addr = TLV320_ADDRESS;
	if (write_regs(client, aud_regs) < 0) {
	if (write_regs(audio, aud_regs) < 0) {
		printk(KERN_ERR
		       "s2250: error initializing audio\n");
		kfree(client);
		i2c_unregister_device(audio);
		kfree(dec);
		return 0;
	}
	client->addr = S2250_VIDDEC;
	i2c_set_clientdata(client, dec);

	if (write_regs(client, vid_regs) < 0) {
		printk(KERN_ERR
		       "s2250: error initializing decoder\n");
		kfree(client);
		i2c_unregister_device(audio);
		kfree(dec);
		return 0;
	}
	if (write_regs_fp(client, vid_regs_fp) < 0) {
		printk(KERN_ERR
		       "s2250: error initializing decoder\n");
		kfree(client);
		i2c_unregister_device(audio);
		kfree(dec);
		return 0;
	}
@@ -575,32 +563,33 @@ static int s2250_detect(struct i2c_adapter *adapter, int addr, int kind)
		up(&usb->i2c_lock);
	}

	i2c_attach_client(client);
	printk("s2250: initialized successfully\n");
	return 0;
}

static int s2250_detach(struct i2c_client *client)
static int s2250_remove(struct i2c_client *client)
{
	struct s2250 *dec = i2c_get_clientdata(client);
	int r;

	r = i2c_detach_client(client);
	if (r < 0)
		return r;

	kfree(client);
	i2c_set_clientdata(client, NULL);
	i2c_unregister_device(dec->audio);
	kfree(dec);
	return 0;
}

static struct i2c_device_id s2250_id[] = {
	{ "s2250_board", 0 },
	{ }
};

static struct i2c_driver s2250_driver = {
	.driver = {
		.name	= "Sensoray 2250 board driver",
	},
	.id		= I2C_DRIVERID_S2250,
	.detach_client	= s2250_detach,
	.probe		= s2250_probe,
	.remove		= s2250_remove,
	.command	= s2250_command,
	.id_table	= s2250_id,
};

static int __init s2250_init(void)
@@ -613,13 +602,13 @@ static int __init s2250_init(void)

	r = i2c_add_driver(&s2250_driver);
	if (r < 0)
		s2250loader_cleanup();

	return r;
	return wis_i2c_add_driver(s2250_driver.id, s2250_detect);
}

static void __exit s2250_cleanup(void)
{
	wis_i2c_del_driver(s2250_detect);
	i2c_del_driver(&s2250_driver);

	s2250loader_cleanup();
Loading