| 1 |
I2C Conversion Guide for I2C-old to the current I2C API |
|---|
| 2 |
July 2002 |
|---|
| 3 |
For Linux Kernel v2.5.x |
|---|
| 4 |
Frank Davis <fdavis@si.rr.com> |
|---|
| 5 |
------------------------------------------------------- |
|---|
| 6 |
|
|---|
| 7 |
There exists several kernel drivers that are using an old version of the I2C |
|---|
| 8 |
API. These drivers need to be converted to the current (kernel 2.5.x) version. |
|---|
| 9 |
The following document provides a guideline to make the appropriate changes to |
|---|
| 10 |
the affected drivers. There maybe slight modifications to this guide that are |
|---|
| 11 |
specific to the driver you are working on. If you see {driver_name}, replace |
|---|
| 12 |
that with the respective name of the driver, such as saa7110.c , {driver_name} |
|---|
| 13 |
= saa7110. |
|---|
| 14 |
|
|---|
| 15 |
------------------------------------------------------- |
|---|
| 16 |
|
|---|
| 17 |
Step 1: Include the right header file |
|---|
| 18 |
|
|---|
| 19 |
Perform the following change within the driver |
|---|
| 20 |
|
|---|
| 21 |
#include <linux/i2c-old.h> --> #include <linux/i2c.h> |
|---|
| 22 |
|
|---|
| 23 |
Step 2: Add and set the i2c modes |
|---|
| 24 |
|
|---|
| 25 |
Add the following code near the top of the driver |
|---|
| 26 |
|
|---|
| 27 |
static unsigned short normal_i2c[] = {34>>1, I2C_CLIENT_END }; |
|---|
| 28 |
static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; |
|---|
| 29 |
static unsigned short probe[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; |
|---|
| 30 |
static unsigned short probe_range[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; |
|---|
| 31 |
static unsigned short ignore[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; |
|---|
| 32 |
static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; |
|---|
| 33 |
static unsigned short force[2] = { I2C_CLIENT_END , I2C_CLIENT_END }; |
|---|
| 34 |
|
|---|
| 35 |
static struct i2c_client_address_data addr_data = { |
|---|
| 36 |
normal_i2c , normal_i2c_range, |
|---|
| 37 |
probe , probe_range, |
|---|
| 38 |
ignore , ignore_range, |
|---|
| 39 |
force |
|---|
| 40 |
}; |
|---|
| 41 |
|
|---|
| 42 |
static struct i2c_client client_template; |
|---|
| 43 |
|
|---|
| 44 |
Step 3: Modify the driver info struct |
|---|
| 45 |
|
|---|
| 46 |
Within the struct for the driver , such as struct {driver_name} , make the |
|---|
| 47 |
following change , |
|---|
| 48 |
struct i2c_bus *bus --> struct i2c_client *client |
|---|
| 49 |
|
|---|
| 50 |
Make changes where this change affects references within the file. |
|---|
| 51 |
|
|---|
| 52 |
Add a semaphore to the driver struct (as above) |
|---|
| 53 |
|
|---|
| 54 |
struct semaphore lock |
|---|
| 55 |
|
|---|
| 56 |
Step 5: Remove specific read and write functions |
|---|
| 57 |
|
|---|
| 58 |
Remove the driver specific write and read functions, usually in the form: |
|---|
| 59 |
{driver_name}_write , {driver_name}_read , {driver_name}_write_block , etc. |
|---|
| 60 |
|
|---|
| 61 |
Step 6: Update the write and read functions for the current I2C API |
|---|
| 62 |
|
|---|
| 63 |
Replace all references of {driver_name}_write with i2c_smbus_write_byte_data |
|---|
| 64 |
Replace all references of {driver_name}_read with i2c_smbus_read_byte_data or |
|---|
| 65 |
i2c_smbus_read_byte , depending on args passed in. |
|---|
| 66 |
|
|---|
| 67 |
** Ensure that these functions pass in the i2c_client *client , NOT the |
|---|
| 68 |
decoder/encoder that was passed in the driver specific write and read |
|---|
| 69 |
functions. |
|---|
| 70 |
|
|---|
| 71 |
Step 7: Modify the driver's attach function |
|---|
| 72 |
|
|---|
| 73 |
Change the driver attach function prototype : |
|---|
| 74 |
{driver_name}_attach(struct i2c_device *device) --> {driver_name}_attach(struct |
|---|
| 75 |
i2c_adapter *adap, int addr , unsigned short flags, int kind) |
|---|
| 76 |
|
|---|
| 77 |
Create a i2c_client client... |
|---|
| 78 |
Add the following (where "decoder" is a reference to a struct for the driver |
|---|
| 79 |
info: |
|---|
| 80 |
|
|---|
| 81 |
struct i2c_client *client; |
|---|
| 82 |
client = kmalloc(sizeof(*client), GFP_KERNEL); |
|---|
| 83 |
if(client == NULL) |
|---|
| 84 |
return -ENOMEM; |
|---|
| 85 |
client_template.adapter = adap; |
|---|
| 86 |
client_template.addr = addr; |
|---|
| 87 |
memcpy(client, &client_template, sizeof(*client)); |
|---|
| 88 |
strcpy(client->name , "{driver_name}"); |
|---|
| 89 |
decoder->client = client; |
|---|
| 90 |
client->data = decoder; |
|---|
| 91 |
decoder->addr = addr; |
|---|
| 92 |
|
|---|
| 93 |
Towards the end of the function, add: |
|---|
| 94 |
|
|---|
| 95 |
init_MUTEX(&decoder->lock); |
|---|
| 96 |
i2c_attach_client(client); |
|---|
| 97 |
|
|---|
| 98 |
|
|---|
| 99 |
Step 8: Modify the driver's detach function |
|---|
| 100 |
|
|---|
| 101 |
Change the driver detach function prototype : |
|---|
| 102 |
{driver_name}_detach(struct i2c_device *device) --> {driver_name}_detach(struct |
|---|
| 103 |
i2c_client *client) |
|---|
| 104 |
|
|---|
| 105 |
In the beginning of the detach function, add: |
|---|
| 106 |
i2c_detach_client(client); |
|---|
| 107 |
|
|---|
| 108 |
Towards the end of the detach function, add: |
|---|
| 109 |
kfree(client->data); |
|---|
| 110 |
kfree(client); |
|---|
| 111 |
|
|---|
| 112 |
Step 9: Modify the driver's command function |
|---|
| 113 |
|
|---|
| 114 |
Change the driver command function prototype : |
|---|
| 115 |
|
|---|
| 116 |
Step 10: Add the probe function after the driver's attach function. |
|---|
| 117 |
|
|---|
| 118 |
Add the following code: |
|---|
| 119 |
|
|---|
| 120 |
static int {driver_name}_probe(struct i2c_adapter *adap) |
|---|
| 121 |
{ |
|---|
| 122 |
return i2c_probe(adap, &addr_data, {driver_name}_attach); |
|---|
| 123 |
|
|---|
| 124 |
} |
|---|
| 125 |
|
|---|
| 126 |
Step 11: Modify the driver's i2c_driver |
|---|
| 127 |
|
|---|
| 128 |
Find the i2c_driver , such as |
|---|
| 129 |
static struct i2c_driver i2c_driver_saa7110 |
|---|
| 130 |
It is usually located towards the end of the driver |
|---|
| 131 |
Replace the values from I2C_DRIVERID_{something} to {driver_name}_attach, and |
|---|
| 132 |
add the following |
|---|
| 133 |
I2C_DRIVERID_{driver_name} , // verify by looking in include/linux/i2c-id.h |
|---|
| 134 |
I2C_DF_NOTIFY, |
|---|
| 135 |
{driver_name}_probe, |
|---|
| 136 |
.... |
|---|
| 137 |
|
|---|
| 138 |
Step 12: Adding the i2c_client |
|---|
| 139 |
|
|---|
| 140 |
Add the i2c_client to the driver. Add the following code: |
|---|
| 141 |
|
|---|
| 142 |
static struct i2c_client client_template = { |
|---|
| 143 |
"{driver_name}_client", |
|---|
| 144 |
-1, |
|---|
| 145 |
0, |
|---|
| 146 |
0, |
|---|
| 147 |
NULL, |
|---|
| 148 |
{i2c_driver reference} |
|---|
| 149 |
}; |
|---|
| 150 |
|
|---|
| 151 |
Step 13: Registering and Unregistering |
|---|
| 152 |
|
|---|
| 153 |
Replace i2c_register_driver with i2c_add_driver |
|---|
| 154 |
Replace i2c_unregister_driver with i2c_del_driver |
|---|
| 155 |
|
|---|
| 156 |
------------------------------------------------------- |
|---|
| 157 |
|
|---|
| 158 |
Example: |
|---|
| 159 |
|
|---|
| 160 |
The following patch provides the i2c coversion patch for the saa7110 driver |
|---|
| 161 |
based on the above guide (for clarity). |
|---|
| 162 |
|
|---|
| 163 |
|
|---|
| 164 |
--- drivers/media/video/saa7110.c.old Fri Jun 28 10:22:52 2002 |
|---|
| 165 |
+++ drivers/media/video/saa7110.c Thu Jul 4 16:51:08 2002 |
|---|
| 166 |
@@ -26,7 +26,7 @@ |
|---|
| 167 |
#include <asm/io.h> |
|---|
| 168 |
#include <asm/uaccess.h> |
|---|
| 169 |
|
|---|
| 170 |
-#include <linux/i2c-old.h> |
|---|
| 171 |
+#include <linux/i2c.h> |
|---|
| 172 |
#include <linux/videodev.h> |
|---|
| 173 |
#include "linux/video_decoder.h" |
|---|
| 174 |
|
|---|
| 175 |
@@ -37,13 +37,31 @@ |
|---|
| 176 |
|
|---|
| 177 |
#define I2C_SAA7110 0x9C /* or 0x9E */ |
|---|
| 178 |
|
|---|
| 179 |
+#define IF_NAME "saa7110" |
|---|
| 180 |
#define I2C_DELAY 10 /* 10 us or 100khz */ |
|---|
| 181 |
|
|---|
| 182 |
+static unsigned short normal_i2c[] = {34>>1, I2C_CLIENT_END }; |
|---|
| 183 |
+static unsigned short normal_i2c_range[] = { I2C_CLIENT_END }; |
|---|
| 184 |
+static unsigned short probe[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; |
|---|
| 185 |
+static unsigned short probe_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; |
|---|
| 186 |
+static unsigned short ignore[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; |
|---|
| 187 |
+static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; |
|---|
| 188 |
+static unsigned short force[2] = { I2C_CLIENT_END, I2C_CLIENT_END }; |
|---|
| 189 |
+ |
|---|
| 190 |
+static struct i2c_client_address_data addr_data = { |
|---|
| 191 |
+ normal_i2c, normal_i2c_range, |
|---|
| 192 |
+ probe, probe_range, |
|---|
| 193 |
+ ignore, ignore_range, |
|---|
| 194 |
+ force |
|---|
| 195 |
+}; |
|---|
| 196 |
+ |
|---|
| 197 |
+static struct i2c_client client_template; |
|---|
| 198 |
+ |
|---|
| 199 |
struct saa7110 { |
|---|
| 200 |
- struct i2c_bus *bus; |
|---|
| 201 |
+ struct i2c_client *client; |
|---|
| 202 |
int addr; |
|---|
| 203 |
unsigned char reg[36]; |
|---|
| 204 |
- |
|---|
| 205 |
+ struct semaphore lock; |
|---|
| 206 |
int norm; |
|---|
| 207 |
int input; |
|---|
| 208 |
int enable; |
|---|
| 209 |
@@ -54,67 +72,10 @@ |
|---|
| 210 |
}; |
|---|
| 211 |
|
|---|
| 212 |
/* ----------------------------------------------------------------------- */ |
|---|
| 213 |
-/* I2C support functions */ |
|---|
| 214 |
-/* ----------------------------------------------------------------------- */ |
|---|
| 215 |
-static |
|---|
| 216 |
-int saa7110_write(struct saa7110 *decoder, unsigned char subaddr, unsigned char data) |
|---|
| 217 |
-{ |
|---|
| 218 |
- int ack; |
|---|
| 219 |
- |
|---|
| 220 |
- LOCK_I2C_BUS(decoder->bus); |
|---|
| 221 |
- i2c_start(decoder->bus); |
|---|
| 222 |
- i2c_sendbyte(decoder->bus, decoder->addr, I2C_DELAY); |
|---|
| 223 |
- i2c_sendbyte(decoder->bus, subaddr, I2C_DELAY); |
|---|
| 224 |
- ack = i2c_sendbyte(decoder->bus, data, I2C_DELAY); |
|---|
| 225 |
- i2c_stop(decoder->bus); |
|---|
| 226 |
- decoder->reg[subaddr] = data; |
|---|
| 227 |
- UNLOCK_I2C_BUS(decoder->bus); |
|---|
| 228 |
- return ack; |
|---|
| 229 |
-} |
|---|
| 230 |
- |
|---|
| 231 |
-static |
|---|
| 232 |
-int saa7110_write_block(struct saa7110* decoder, unsigned const char *data, unsigned int len) |
|---|
| 233 |
-{ |
|---|
| 234 |
- unsigned subaddr = *data; |
|---|
| 235 |
- |
|---|
| 236 |
- LOCK_I2C_BUS(decoder->bus); |
|---|
| 237 |
- i2c_start(decoder->bus); |
|---|
| 238 |
- i2c_sendbyte(decoder->bus,decoder->addr,I2C_DELAY); |
|---|
| 239 |
- while (len-- > 0) { |
|---|
| 240 |
- if (i2c_sendbyte(decoder->bus,*data,0)) { |
|---|
| 241 |
- i2c_stop(decoder->bus); |
|---|
| 242 |
- UNLOCK_I2C_BUS(decoder->bus); |
|---|
| 243 |
- return -EAGAIN; |
|---|
| 244 |
- } |
|---|
| 245 |
- decoder->reg[subaddr++] = *data++; |
|---|
| 246 |
- } |
|---|
| 247 |
- i2c_stop(decoder->bus); |
|---|
| 248 |
- UNLOCK_I2C_BUS(decoder->bus); |
|---|
| 249 |
- |
|---|
| 250 |
- return 0; |
|---|
| 251 |
-} |
|---|
| 252 |
- |
|---|
| 253 |
-static |
|---|
| 254 |
-int saa7110_read(struct saa7110* decoder) |
|---|
| 255 |
-{ |
|---|
| 256 |
- int data; |
|---|
| 257 |
- |
|---|
| 258 |
- LOCK_I2C_BUS(decoder->bus); |
|---|
| 259 |
- i2c_start(decoder->bus); |
|---|
| 260 |
- i2c_sendbyte(decoder->bus, decoder->addr, I2C_DELAY); |
|---|
| 261 |
- i2c_start(decoder->bus); |
|---|
| 262 |
- i2c_sendbyte(decoder->bus, decoder->addr | 1, I2C_DELAY); |
|---|
| 263 |
- data = i2c_readbyte(decoder->bus, 1); |
|---|
| 264 |
- i2c_stop(decoder->bus); |
|---|
| 265 |
- UNLOCK_I2C_BUS(decoder->bus); |
|---|
| 266 |
- return data; |
|---|
| 267 |
-} |
|---|
| 268 |
- |
|---|
| 269 |
-/* ----------------------------------------------------------------------- */ |
|---|
| 270 |
/* SAA7110 functions */ |
|---|
| 271 |
/* ----------------------------------------------------------------------- */ |
|---|
| 272 |
static |
|---|
| 273 |
-int saa7110_selmux(struct i2c_device *device, int chan) |
|---|
| 274 |
+int saa7110_selmux(struct i2c_client *client, int chan) |
|---|
| 275 |
{ |
|---|
| 276 |
static const unsigned char modes[9][8] = { |
|---|
| 277 |
/* mode 0 */ { 0x00, 0xD9, 0x17, 0x40, 0x03, 0x44, 0x75, 0x16 }, |
|---|
| 278 |
@@ -126,61 +87,59 @@ |
|---|
| 279 |
/* mode 6 */ { 0x80, 0x59, 0x17, 0x42, 0xA3, 0x44, 0x75, 0x12 }, |
|---|
| 280 |
/* mode 7 */ { 0x80, 0x9A, 0x17, 0xB1, 0x13, 0x60, 0xB5, 0x14 }, |
|---|
| 281 |
/* mode 8 */ { 0x80, 0x3C, 0x27, 0xC1, 0x23, 0x44, 0x75, 0x21 } }; |
|---|
| 282 |
- struct saa7110* decoder = device->data; |
|---|
| 283 |
const unsigned char* ptr = modes[chan]; |
|---|
| 284 |
|
|---|
| 285 |
- saa7110_write(decoder,0x06,ptr[0]); /* Luminance control */ |
|---|
| 286 |
- saa7110_write(decoder,0x20,ptr[1]); /* Analog Control #1 */ |
|---|
| 287 |
- saa7110_write(decoder,0x21,ptr[2]); /* Analog Control #2 */ |
|---|
| 288 |
- saa7110_write(decoder,0x22,ptr[3]); /* Mixer Control #1 */ |
|---|
| 289 |
- saa7110_write(decoder,0x2C,ptr[4]); /* Mixer Control #2 */ |
|---|
| 290 |
- saa7110_write(decoder,0x30,ptr[5]); /* ADCs gain control */ |
|---|
| 291 |
- saa7110_write(decoder,0x31,ptr[6]); /* Mixer Control #3 */ |
|---|
| 292 |
- saa7110_write(decoder,0x21,ptr[7]); /* Analog Control #2 */ |
|---|
| 293 |
+ i2c_smbus_write_byte_data(client,0x06,ptr[0]); /* Luminance control */ |
|---|
| 294 |
+ i2c_smbus_write_byte_data(client,0x20,ptr[1]); /* Analog Control #1 */ |
|---|
| 295 |
+ i2c_smbus_write_byte_data(client,0x21,ptr[2]); /* Analog Control #2 */ |
|---|
| 296 |
+ i2c_smbus_write_byte_data(client,0x22,ptr[3]); /* Mixer Control #1 */ |
|---|
| 297 |
+ i2c_smbus_write_byte_data(client,0x2C,ptr[4]); /* Mixer Control #2 */ |
|---|
| 298 |
+ i2c_smbus_write_byte_data(client,0x30,ptr[5]); /* ADCs gain control */ |
|---|
| 299 |
+ i2c_smbus_write_byte_data(client,0x31,ptr[6]); /* Mixer Control #3 */ |
|---|
| 300 |
+ i2c_smbus_write_byte_data(client,0x21,ptr[7]); /* Analog Control #2 */ |
|---|
| 301 |
|
|---|
| 302 |
return 0; |
|---|
| 303 |
} |
|---|
| 304 |
|
|---|
| 305 |
static |
|---|
| 306 |
-int determine_norm(struct i2c_device* dev) |
|---|
| 307 |
+int determine_norm(struct i2c_client* client) |
|---|
| 308 |
{ |
|---|
| 309 |
- struct saa7110* decoder = dev->data; |
|---|
| 310 |
int status; |
|---|
| 311 |
|
|---|
| 312 |
/* mode changed, start automatic detection */ |
|---|
| 313 |
- status = saa7110_read(decoder); |
|---|
| 314 |
+ status = i2c_smbus_read_byte(client); |
|---|
| 315 |
if ((status & 3) == 0) { |
|---|
| 316 |
- saa7110_write(decoder,0x06,0x80); |
|---|
| 317 |
+ i2c_smbus_write_byte_data(client,0x06,0x80); |
|---|
| 318 |
if (status & 0x20) { |
|---|
| 319 |
- DEBUG(printk(KERN_INFO "%s: norm=bw60\n",dev->name)); |
|---|
| 320 |
- saa7110_write(decoder,0x2E,0x81); |
|---|
| 321 |
+ DEBUG(printk(KERN_INFO "%s: norm=bw60\n",adp->name)); |
|---|
| 322 |
+ i2c_smbus_write_byte_data(client,0x2E,0x81); |
|---|
| 323 |
return VIDEO_MODE_NTSC; |
|---|
| 324 |
} |
|---|
| 325 |
- DEBUG(printk(KERN_INFO "%s: norm=bw50\n",dev->name)); |
|---|
| 326 |
- saa7110_write(decoder,0x2E,0x9A); |
|---|
| 327 |
+ DEBUG(printk(KERN_INFO "%s: norm=bw50\n",adp->name)); |
|---|
| 328 |
+ i2c_smbus_write_byte_data(client,0x2E,0x9A); |
|---|
| 329 |
return VIDEO_MODE_PAL; |
|---|
| 330 |
} |
|---|
| 331 |
|
|---|
| 332 |
- saa7110_write(decoder,0x06,0x00); |
|---|
| 333 |
+ i2c_smbus_write_byte_data(client,0x06,0x00); |
|---|
| 334 |
if (status & 0x20) { /* 60Hz */ |
|---|
| 335 |
- DEBUG(printk(KERN_INFO "%s: norm=ntsc\n",dev->name)); |
|---|
| 336 |
- saa7110_write(decoder,0x0D,0x06); |
|---|
| 337 |
- saa7110_write(decoder,0x11,0x2C); |
|---|
| 338 |
- saa7110_write(decoder,0x2E,0x81); |
|---|
| 339 |
+ DEBUG(printk(KERN_INFO "%s: norm=ntsc\n",adp->name)); |
|---|
| 340 |
+ i2c_smbus_write_byte_data(client,0x0D,0x06); |
|---|
| 341 |
+ i2c_smbus_write_byte_data(client,0x11,0x2C); |
|---|
| 342 |
+ i2c_smbus_write_byte_data(client,0x2E,0x81); |
|---|
| 343 |
return VIDEO_MODE_NTSC; |
|---|
| 344 |
} |
|---|
| 345 |
|
|---|
| 346 |
/* 50Hz -> PAL/SECAM */ |
|---|
| 347 |
- saa7110_write(decoder,0x0D,0x06); |
|---|
| 348 |
- saa7110_write(decoder,0x11,0x59); |
|---|
| 349 |
- saa7110_write(decoder,0x2E,0x9A); |
|---|
| 350 |
+ i2c_smbus_write_byte_data(client,0x0D,0x06); |
|---|
| 351 |
+ i2c_smbus_write_byte_data(client,0x11,0x59); |
|---|
| 352 |
+ i2c_smbus_write_byte_data(client,0x2E,0x9A); |
|---|
| 353 |
|
|---|
| 354 |
mdelay(150); /* pause 150 ms */ |
|---|
| 355 |
|
|---|
| 356 |
- status = saa7110_read(decoder); |
|---|
| 357 |
+ status = i2c_smbus_read_byte(client); |
|---|
| 358 |
if ((status & 0x03) == 0x01) { |
|---|
| 359 |
DEBUG(printk(KERN_INFO "%s: norm=secam\n",dev->name)); |
|---|
| 360 |
- saa7110_write(decoder,0x0D,0x07); |
|---|
| 361 |
+ i2c_smbus_write_byte_data(client,0x0D,0x07); |
|---|
| 362 |
return VIDEO_MODE_SECAM; |
|---|
| 363 |
} |
|---|
| 364 |
DEBUG(printk(KERN_INFO "%s: norm=pal\n",dev->name)); |
|---|
| 365 |
@@ -188,7 +147,7 @@ |
|---|
| 366 |
} |
|---|
| 367 |
|
|---|
| 368 |
static |
|---|
| 369 |
-int saa7110_attach(struct i2c_device *device) |
|---|
| 370 |
+int saa7110_attach(struct i2c_adapter *adap, int addr, unsigned short flags, int kind) |
|---|
| 371 |
{ |
|---|
| 372 |
static const unsigned char initseq[] = { |
|---|
| 373 |
0, 0x4C, 0x3C, 0x0D, 0xEF, 0xBD, 0xF0, 0x00, 0x00, |
|---|
| 374 |
@@ -198,20 +157,28 @@ |
|---|
| 375 |
0xD9, 0x17, 0x40, 0x41, 0x80, 0x41, 0x80, 0x4F, |
|---|
| 376 |
0xFE, 0x01, 0xCF, 0x0F, 0x03, 0x01, 0x81, 0x03, |
|---|
| 377 |
0x40, 0x75, 0x01, 0x8C, 0x03}; |
|---|
| 378 |
- struct saa7110* decoder; |
|---|
| 379 |
+ struct saa7110 *decoder; |
|---|
| 380 |
+ struct i2c_client *client; |
|---|
| 381 |
int rv; |
|---|
| 382 |
- |
|---|
| 383 |
- device->data = decoder = kmalloc(sizeof(struct saa7110), GFP_KERNEL); |
|---|
| 384 |
- if (device->data == 0) |
|---|
| 385 |
+ client=kmalloc(sizeof(*client), GFP_KERNEL); |
|---|
| 386 |
+ if(client == NULL) |
|---|
| 387 |
return -ENOMEM; |
|---|
| 388 |
- |
|---|
| 389 |
- MOD_INC_USE_COUNT; |
|---|
| 390 |
+ client_template.adapter = adap; |
|---|
| 391 |
+ client_template.addr = addr; |
|---|
| 392 |
+ memcpy(client, &client_template, sizeof(*client)); |
|---|
| 393 |
+ |
|---|
| 394 |
+ decoder = kmalloc(sizeof(*decoder), GFP_KERNEL); |
|---|
| 395 |
+ if (decoder == NULL) { |
|---|
| 396 |
+ kfree(client); |
|---|
| 397 |
+ return -ENOMEM; |
|---|
| 398 |
+ } |
|---|
| 399 |
|
|---|
| 400 |
/* clear our private data */ |
|---|
| 401 |
- memset(decoder, 0, sizeof(struct saa7110)); |
|---|
| 402 |
- strcpy(device->name, "saa7110"); |
|---|
| 403 |
- decoder->bus = device->bus; |
|---|
| 404 |
- decoder->addr = device->addr; |
|---|
| 405 |
+ memset(decoder, 0, sizeof(*decoder)); |
|---|
| 406 |
+ strcpy(client->name, IF_NAME); |
|---|
| 407 |
+ decoder->client = client; |
|---|
| 408 |
+ client->data = decoder; |
|---|
| 409 |
+ decoder->addr = addr; |
|---|
| 410 |
decoder->norm = VIDEO_MODE_PAL; |
|---|
| 411 |
decoder->input = 0; |
|---|
| 412 |
decoder->enable = 1; |
|---|
| 413 |
@@ -220,40 +187,52 @@ |
|---|
| 414 |
decoder->hue = 32768; |
|---|
| 415 |
decoder->sat = 32768; |
|---|
| 416 |
|
|---|
| 417 |
- rv = saa7110_write_block(decoder, initseq, sizeof(initseq)); |
|---|
| 418 |
+ rv = i2c_master_send(client, initseq, sizeof(initseq)); |
|---|
| 419 |
if (rv < 0) |
|---|
| 420 |
- printk(KERN_ERR "%s_attach: init status %d\n", device->name, rv); |
|---|
| 421 |
+ printk(KERN_ERR "%s_attach: init status %d\n", client->name, rv); |
|---|
| 422 |
else { |
|---|
| 423 |
- saa7110_write(decoder,0x21,0x16); |
|---|
| 424 |
- saa7110_write(decoder,0x0D,0x04); |
|---|
| 425 |
- DEBUG(printk(KERN_INFO "%s_attach: chip version %x\n", device->name, saa7110_read(decoder))); |
|---|
| 426 |
- saa7110_write(decoder,0x0D,0x06); |
|---|
| 427 |
+ i2c_smbus_write_byte_data(client,0x21,0x16); |
|---|
| 428 |
+ i2c_smbus_write_byte_data(client,0x0D,0x04); |
|---|
| 429 |
+ DEBUG(printk(KERN_INFO "%s_attach: chip version %x\n", client->name, i2c_smbus_read_byte(client))); |
|---|
| 430 |
+ i2c_smbus_write_byte_data(client,0x0D,0x06); |
|---|
| 431 |
} |
|---|
| 432 |
|
|---|
| 433 |
+ init_MUTEX(&decoder->lock); |
|---|
| 434 |
+ i2c_attach_client(client); |
|---|
| 435 |
+ MOD_INC_USE_COUNT; |
|---|
| 436 |
/* setup and implicit mode 0 select has been performed */ |
|---|
| 437 |
return 0; |
|---|
| 438 |
} |
|---|
| 439 |
|
|---|
| 440 |
+static |
|---|
| 441 |
+int saa7110_probe(struct i2c_adapter *adap) |
|---|
| 442 |
+{ |
|---|
| 443 |
+ return i2c_probe(adap, &addr_data, saa7110_attach); |
|---|
| 444 |
+} |
|---|
| 445 |
+ |
|---|
| 446 |
static |
|---|
| 447 |
-int saa7110_detach(struct i2c_device *device) |
|---|
| 448 |
+int saa7110_detach(struct i2c_client *client) |
|---|
| 449 |
{ |
|---|
| 450 |
- struct saa7110* decoder = device->data; |
|---|
| 451 |
+ struct saa7110* decoder = client->data; |
|---|
| 452 |
|
|---|
| 453 |
- DEBUG(printk(KERN_INFO "%s_detach\n",device->name)); |
|---|
| 454 |
+ i2c_detach_client(client); |
|---|
| 455 |
+ |
|---|
| 456 |
+ DEBUG(printk(KERN_INFO "%s_detach\n",client->name)); |
|---|
| 457 |
|
|---|
| 458 |
/* stop further output */ |
|---|
| 459 |
- saa7110_write(decoder,0x0E,0x00); |
|---|
| 460 |
+ i2c_smbus_write_byte_data(client,0x0E,0x00); |
|---|
| 461 |
|
|---|
| 462 |
- kfree(device->data); |
|---|
| 463 |
+ kfree(decoder); |
|---|
| 464 |
+ kfree(client); |
|---|
| 465 |
|
|---|
| 466 |
MOD_DEC_USE_COUNT; |
|---|
| 467 |
return 0; |
|---|
| 468 |
} |
|---|
| 469 |
|
|---|
| 470 |
static |
|---|
| 471 |
-int saa7110_command(struct i2c_device *device, unsigned int cmd, void *arg) |
|---|
| 472 |
+int saa7110_command(struct i2c_client *client, unsigned int cmd, void *arg) |
|---|
| 473 |
{ |
|---|
| 474 |
- struct saa7110* decoder = device->data; |
|---|
| 475 |
+ struct saa7110* decoder = client->data; |
|---|
| 476 |
int v; |
|---|
| 477 |
|
|---|
| 478 |
switch (cmd) { |
|---|
| 479 |
@@ -272,11 +251,11 @@ |
|---|
| 480 |
|
|---|
| 481 |
case DECODER_GET_STATUS: |
|---|
| 482 |
{ |
|---|
| 483 |
- struct saa7110* decoder = device->data; |
|---|
| 484 |
+ struct saa7110* decoder = client->data; |
|---|
| 485 |
int status; |
|---|
| 486 |
int res = 0; |
|---|
| 487 |
|
|---|
| 488 |
- status = i2c_read(device->bus,device->addr|1); |
|---|
| 489 |
+ status = i2c_smbus_read_byte(client); |
|---|
| 490 |
if (status & 0x40) |
|---|
| 491 |
res |= DECODER_STATUS_GOOD; |
|---|
| 492 |
if (status & 0x03) |
|---|
| 493 |
@@ -301,26 +280,26 @@ |
|---|
| 494 |
v = *(int*)arg; |
|---|
| 495 |
if (decoder->norm != v) { |
|---|
| 496 |
decoder->norm = v; |
|---|
| 497 |
- saa7110_write(decoder, 0x06, 0x00); |
|---|
| 498 |
+ i2c_smbus_write_byte_data(client, 0x06, 0x00); |
|---|
| 499 |
switch (v) { |
|---|
| 500 |
case VIDEO_MODE_NTSC: |
|---|
| 501 |
- saa7110_write(decoder, 0x0D, 0x06); |
|---|
| 502 |
- saa7110_write(decoder, 0x11, 0x2C); |
|---|
| 503 |
- saa7110_write(decoder, 0x30, 0x81); |
|---|
| 504 |
- saa7110_write(decoder, 0x2A, 0xDF); |
|---|
| 505 |
+ i2c_smbus_write_byte_data(client, 0x0D, 0x06); |
|---|
| 506 |
+ i2c_smbus_write_byte_data(client, 0x11, 0x2C); |
|---|
| 507 |
+ i2c_smbus_write_byte_data(client, 0x30, 0x81); |
|---|
| 508 |
+ i2c_smbus_write_byte_data(client, 0x2A, 0xDF); |
|---|
| 509 |
break; |
|---|
| 510 |
case VIDEO_MODE_PAL: |
|---|
| 511 |
- saa7110_write(decoder, 0x0D, 0x06); |
|---|
| 512 |
- saa7110_write(decoder, 0x11, 0x59); |
|---|
| 513 |
- saa7110_write(decoder, 0x2E, 0x9A); |
|---|
| 514 |
+ i2c_smbus_write_byte_data(client, 0x0D, 0x06); |
|---|
| 515 |
+ i2c_smbus_write_byte_data(client, 0x11, 0x59); |
|---|
| 516 |
+ i2c_smbus_write_byte_data(client, 0x2E, 0x9A); |
|---|
| 517 |
break; |
|---|
| 518 |
case VIDEO_MODE_SECAM: |
|---|
| 519 |
- saa7110_write(decoder, 0x0D, 0x07); |
|---|
| 520 |
- saa7110_write(decoder, 0x11, 0x59); |
|---|
| 521 |
- saa7110_write(decoder, 0x2E, 0x9A); |
|---|
| 522 |
+ i2c_smbus_write_byte_data(client, 0x0D, 0x07); |
|---|
| 523 |
+ i2c_smbus_write_byte_data(client, 0x11, 0x59); |
|---|
| 524 |
+ i2c_smbus_write_byte_data(client, 0x2E, 0x9A); |
|---|
| 525 |
break; |
|---|
| 526 |
case VIDEO_MODE_AUTO: |
|---|
| 527 |
- *(int*)arg = determine_norm(device); |
|---|
| 528 |
+ *(int*)arg = determine_norm(client); |
|---|
| 529 |
break; |
|---|
| 530 |
default: |
|---|
| 531 |
return -EPERM; |
|---|
| 532 |
@@ -334,7 +313,7 @@ |
|---|
| 533 |
return -EINVAL; |
|---|
| 534 |
if (decoder->input != v) { |
|---|
| 535 |
decoder->input = v; |
|---|
| 536 |
- saa7110_selmux(device, v); |
|---|
| 537 |
+ saa7110_selmux(client, v); |
|---|
| 538 |
} |
|---|
| 539 |
break; |
|---|
| 540 |
|
|---|
| 541 |
@@ -349,7 +328,7 @@ |
|---|
| 542 |
v = *(int*)arg; |
|---|
| 543 |
if (decoder->enable != v) { |
|---|
| 544 |
decoder->enable = v; |
|---|
| 545 |
- saa7110_write(decoder,0x0E, v ? 0x18 : 0x00); |
|---|
| 546 |
+ i2c_smbus_write_byte_data(client,0x0E, v ? 0x18 : 0x00); |
|---|
| 547 |
} |
|---|
| 548 |
break; |
|---|
| 549 |
|
|---|
| 550 |
@@ -360,22 +339,22 @@ |
|---|
| 551 |
if (decoder->bright != pic->brightness) { |
|---|
| 552 |
/* We want 0 to 255 we get 0-65535 */ |
|---|
| 553 |
decoder->bright = pic->brightness; |
|---|
| 554 |
- saa7110_write(decoder, 0x19, decoder->bright >> 8); |
|---|
| 555 |
+ i2c_smbus_write_byte_data(client, 0x19, decoder->bright >> 8); |
|---|
| 556 |
} |
|---|
| 557 |
if (decoder->contrast != pic->contrast) { |
|---|
| 558 |
/* We want 0 to 127 we get 0-65535 */ |
|---|
| 559 |
decoder->contrast = pic->contrast; |
|---|
| 560 |
- saa7110_write(decoder, 0x13, decoder->contrast >> 9); |
|---|
| 561 |
+ i2c_smbus_write_byte_data(client, 0x13, decoder->contrast >> 9); |
|---|
| 562 |
} |
|---|
| 563 |
if (decoder->sat != pic->colour) { |
|---|
| 564 |
/* We want 0 to 127 we get 0-65535 */ |
|---|
| 565 |
decoder->sat = pic->colour; |
|---|
| 566 |
- saa7110_write(decoder, 0x12, decoder->sat >> 9); |
|---|
| 567 |
+ i2c_smbus_write_byte_data(client, 0x12, decoder->sat >> 9); |
|---|
| 568 |
} |
|---|
| 569 |
if (decoder->hue != pic->hue) { |
|---|
| 570 |
/* We want -128 to 127 we get 0-65535 */ |
|---|
| 571 |
decoder->hue = pic->hue; |
|---|
| 572 |
- saa7110_write(decoder, 0x07, (decoder->hue>>8)-128); |
|---|
| 573 |
+ i2c_smbus_write_byte_data(client, 0x07, (decoder->hue>>8)-128); |
|---|
| 574 |
} |
|---|
| 575 |
} |
|---|
| 576 |
break; |
|---|
| 577 |
@@ -383,7 +362,7 @@ |
|---|
| 578 |
case DECODER_DUMP: |
|---|
| 579 |
for (v=0; v<34; v+=16) { |
|---|
| 580 |
int j; |
|---|
| 581 |
- DEBUG(printk(KERN_INFO "%s: %03x\n",device->name,v)); |
|---|
| 582 |
+ DEBUG(printk(KERN_INFO "%s: %03x\n",client->name,v)); |
|---|
| 583 |
for (j=0; j<16; j++) { |
|---|
| 584 |
DEBUG(printk(KERN_INFO " %02x",decoder->reg[v+j])); |
|---|
| 585 |
} |
|---|
| 586 |
@@ -402,24 +381,30 @@ |
|---|
| 587 |
|
|---|
| 588 |
static struct i2c_driver i2c_driver_saa7110 = |
|---|
| 589 |
{ |
|---|
| 590 |
- "saa7110", /* name */ |
|---|
| 591 |
- |
|---|
| 592 |
- I2C_DRIVERID_VIDEODECODER, /* in i2c.h */ |
|---|
| 593 |
- I2C_SAA7110, I2C_SAA7110+1, /* Addr range */ |
|---|
| 594 |
- |
|---|
| 595 |
- saa7110_attach, |
|---|
| 596 |
+ IF_NAME, /* name */ |
|---|
| 597 |
+ I2C_DRIVERID_SAA7110, /* in i2c.h */ |
|---|
| 598 |
+ I2C_DF_NOTIFY, /* Addr range */ |
|---|
| 599 |
+ saa7110_probe, |
|---|
| 600 |
saa7110_detach, |
|---|
| 601 |
saa7110_command |
|---|
| 602 |
}; |
|---|
| 603 |
+static struct i2c_client client_template = { |
|---|
| 604 |
+ "saa7110_client", |
|---|
| 605 |
+ -1, |
|---|
| 606 |
+ 0, |
|---|
| 607 |
+ 0, |
|---|
| 608 |
+ NULL, |
|---|
| 609 |
+ &i2c_driver_saa7110 |
|---|
| 610 |
+}; |
|---|
| 611 |
|
|---|
| 612 |
static int saa7110_init(void) |
|---|
| 613 |
{ |
|---|
| 614 |
- return i2c_register_driver(&i2c_driver_saa7110); |
|---|
| 615 |
+ return i2c_add_driver(&i2c_driver_saa7110); |
|---|
| 616 |
} |
|---|
| 617 |
|
|---|
| 618 |
static void saa7110_exit(void) |
|---|
| 619 |
{ |
|---|
| 620 |
- i2c_unregister_driver(&i2c_driver_saa7110); |
|---|
| 621 |
+ i2c_del_driver(&i2c_driver_saa7110); |
|---|
| 622 |
} |
|---|
| 623 |
|
|---|
| 624 |
|
|---|
| 625 |
|
|---|
| 626 |
|
|---|