diff options
Diffstat (limited to 'drivers/media/video/cx18/cx18-i2c.c')
-rw-r--r-- | drivers/media/video/cx18/cx18-i2c.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c index aa09e557b195..8941f58bed7f 100644 --- a/drivers/media/video/cx18/cx18-i2c.c +++ b/drivers/media/video/cx18/cx18-i2c.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Derived from ivtv-i2c.c | 4 | * Derived from ivtv-i2c.c |
5 | * | 5 | * |
6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> | 6 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> |
7 | * Copyright (C) 2008 Andy Walls <awalls@radix.net> | ||
7 | * | 8 | * |
8 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
@@ -27,6 +28,7 @@ | |||
27 | #include "cx18-gpio.h" | 28 | #include "cx18-gpio.h" |
28 | #include "cx18-av-core.h" | 29 | #include "cx18-av-core.h" |
29 | #include "cx18-i2c.h" | 30 | #include "cx18-i2c.h" |
31 | #include "cx18-irq.h" | ||
30 | 32 | ||
31 | #define CX18_REG_I2C_1_WR 0xf15000 | 33 | #define CX18_REG_I2C_1_WR 0xf15000 |
32 | #define CX18_REG_I2C_1_RD 0xf15008 | 34 | #define CX18_REG_I2C_1_RD 0xf15008 |
@@ -160,9 +162,9 @@ static void cx18_setscl(void *data, int state) | |||
160 | u32 r = cx18_read_reg(cx, addr); | 162 | u32 r = cx18_read_reg(cx, addr); |
161 | 163 | ||
162 | if (state) | 164 | if (state) |
163 | cx18_write_reg_sync(cx, r | SETSCL_BIT, addr); | 165 | cx18_write_reg(cx, r | SETSCL_BIT, addr); |
164 | else | 166 | else |
165 | cx18_write_reg_sync(cx, r & ~SETSCL_BIT, addr); | 167 | cx18_write_reg(cx, r & ~SETSCL_BIT, addr); |
166 | } | 168 | } |
167 | 169 | ||
168 | static void cx18_setsda(void *data, int state) | 170 | static void cx18_setsda(void *data, int state) |
@@ -173,9 +175,9 @@ static void cx18_setsda(void *data, int state) | |||
173 | u32 r = cx18_read_reg(cx, addr); | 175 | u32 r = cx18_read_reg(cx, addr); |
174 | 176 | ||
175 | if (state) | 177 | if (state) |
176 | cx18_write_reg_sync(cx, r | SETSDL_BIT, addr); | 178 | cx18_write_reg(cx, r | SETSDL_BIT, addr); |
177 | else | 179 | else |
178 | cx18_write_reg_sync(cx, r & ~SETSDL_BIT, addr); | 180 | cx18_write_reg(cx, r & ~SETSDL_BIT, addr); |
179 | } | 181 | } |
180 | 182 | ||
181 | static int cx18_getscl(void *data) | 183 | static int cx18_getscl(void *data) |
@@ -396,30 +398,33 @@ int init_cx18_i2c(struct cx18 *cx) | |||
396 | if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) { | 398 | if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) { |
397 | /* Reset/Unreset I2C hardware block */ | 399 | /* Reset/Unreset I2C hardware block */ |
398 | /* Clock select 220MHz */ | 400 | /* Clock select 220MHz */ |
399 | cx18_write_reg(cx, 0x10000000, 0xc71004); | 401 | cx18_write_reg_expect(cx, 0x10000000, 0xc71004, |
402 | 0x00000000, 0x10001000); | ||
400 | /* Clock Enable */ | 403 | /* Clock Enable */ |
401 | cx18_write_reg_sync(cx, 0x10001000, 0xc71024); | 404 | cx18_write_reg_expect(cx, 0x10001000, 0xc71024, |
405 | 0x00001000, 0x10001000); | ||
402 | } | 406 | } |
403 | /* courtesy of Steven Toth <stoth@hauppauge.com> */ | 407 | /* courtesy of Steven Toth <stoth@hauppauge.com> */ |
404 | cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c); | 408 | cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0); |
405 | mdelay(10); | 409 | mdelay(10); |
406 | cx18_write_reg_sync(cx, 0x00c000c0, 0xc7001c); | 410 | cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0); |
407 | mdelay(10); | 411 | mdelay(10); |
408 | cx18_write_reg_sync(cx, 0x00c00000, 0xc7001c); | 412 | cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0); |
409 | mdelay(10); | 413 | mdelay(10); |
410 | 414 | ||
411 | /* Set to edge-triggered intrs. */ | 415 | /* Set to edge-triggered intrs. */ |
412 | cx18_write_reg_sync(cx, 0x00c00000, 0xc730c8); | 416 | cx18_write_reg(cx, 0x00c00000, 0xc730c8); |
413 | /* Clear any stale intrs */ | 417 | /* Clear any stale intrs */ |
414 | cx18_write_reg_sync(cx, 0x00c00000, 0xc730c4); | 418 | cx18_write_reg_expect(cx, HW2_I2C1_INT|HW2_I2C2_INT, HW2_INT_CLR_STATUS, |
419 | ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT); | ||
415 | 420 | ||
416 | /* Hw I2C1 Clock Freq ~100kHz */ | 421 | /* Hw I2C1 Clock Freq ~100kHz */ |
417 | cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR); | 422 | cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR); |
418 | cx18_setscl(&cx->i2c_algo_cb_data[0], 1); | 423 | cx18_setscl(&cx->i2c_algo_cb_data[0], 1); |
419 | cx18_setsda(&cx->i2c_algo_cb_data[0], 1); | 424 | cx18_setsda(&cx->i2c_algo_cb_data[0], 1); |
420 | 425 | ||
421 | /* Hw I2C2 Clock Freq ~100kHz */ | 426 | /* Hw I2C2 Clock Freq ~100kHz */ |
422 | cx18_write_reg_sync(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR); | 427 | cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR); |
423 | cx18_setscl(&cx->i2c_algo_cb_data[1], 1); | 428 | cx18_setscl(&cx->i2c_algo_cb_data[1], 1); |
424 | cx18_setsda(&cx->i2c_algo_cb_data[1], 1); | 429 | cx18_setsda(&cx->i2c_algo_cb_data[1], 1); |
425 | 430 | ||