diff options
Diffstat (limited to 'drivers/media/video/cx25840/cx25840-firmware.c')
-rw-r--r-- | drivers/media/video/cx25840/cx25840-firmware.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/media/video/cx25840/cx25840-firmware.c b/drivers/media/video/cx25840/cx25840-firmware.c index df9d50a75542..e1a7823d82cd 100644 --- a/drivers/media/video/cx25840/cx25840-firmware.c +++ b/drivers/media/video/cx25840/cx25840-firmware.c | |||
@@ -15,7 +15,6 @@ | |||
15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 15 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | |||
19 | #include <linux/module.h> | 18 | #include <linux/module.h> |
20 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
21 | #include <linux/i2c-algo-bit.h> | 20 | #include <linux/i2c-algo-bit.h> |
@@ -38,7 +37,7 @@ module_param(firmware, charp, 0444); | |||
38 | MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]"); | 37 | MODULE_PARM_DESC(fastfw, "Load firmware fast [0=100MHz 1=333MHz (default)]"); |
39 | MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); | 38 | MODULE_PARM_DESC(firmware, "Firmware image [default: " FWFILE "]"); |
40 | 39 | ||
41 | static inline void set_i2c_delay(struct i2c_client *client, int delay) | 40 | static void set_i2c_delay(struct i2c_client *client, int delay) |
42 | { | 41 | { |
43 | struct i2c_algo_bit_data *algod = client->adapter->algo_data; | 42 | struct i2c_algo_bit_data *algod = client->adapter->algo_data; |
44 | 43 | ||
@@ -52,7 +51,7 @@ static inline void set_i2c_delay(struct i2c_client *client, int delay) | |||
52 | } | 51 | } |
53 | } | 52 | } |
54 | 53 | ||
55 | static inline void start_fw_load(struct i2c_client *client) | 54 | static void start_fw_load(struct i2c_client *client) |
56 | { | 55 | { |
57 | /* DL_ADDR_LB=0 DL_ADDR_HB=0 */ | 56 | /* DL_ADDR_LB=0 DL_ADDR_HB=0 */ |
58 | cx25840_write(client, 0x800, 0x00); | 57 | cx25840_write(client, 0x800, 0x00); |
@@ -66,7 +65,7 @@ static inline void start_fw_load(struct i2c_client *client) | |||
66 | set_i2c_delay(client, 3); | 65 | set_i2c_delay(client, 3); |
67 | } | 66 | } |
68 | 67 | ||
69 | static inline void end_fw_load(struct i2c_client *client) | 68 | static void end_fw_load(struct i2c_client *client) |
70 | { | 69 | { |
71 | if (fastfw) | 70 | if (fastfw) |
72 | set_i2c_delay(client, 10); | 71 | set_i2c_delay(client, 10); |
@@ -77,38 +76,47 @@ static inline void end_fw_load(struct i2c_client *client) | |||
77 | cx25840_write(client, 0x803, 0x03); | 76 | cx25840_write(client, 0x803, 0x03); |
78 | } | 77 | } |
79 | 78 | ||
80 | static inline int check_fw_load(struct i2c_client *client, int size) | 79 | static int check_fw_load(struct i2c_client *client, int size) |
81 | { | 80 | { |
82 | /* DL_ADDR_HB DL_ADDR_LB */ | 81 | /* DL_ADDR_HB DL_ADDR_LB */ |
83 | int s = cx25840_read(client, 0x801) << 8; | 82 | int s = cx25840_read(client, 0x801) << 8; |
84 | s |= cx25840_read(client, 0x800); | 83 | s |= cx25840_read(client, 0x800); |
85 | 84 | ||
86 | if (size != s) { | 85 | if (size != s) { |
87 | cx25840_err("firmware %s load failed\n", firmware); | 86 | v4l_err(client, "firmware %s load failed\n", firmware); |
88 | return -EINVAL; | 87 | return -EINVAL; |
89 | } | 88 | } |
90 | 89 | ||
91 | cx25840_info("loaded %s firmware (%d bytes)\n", firmware, size); | 90 | v4l_info(client, "loaded %s firmware (%d bytes)\n", firmware, size); |
92 | return 0; | 91 | return 0; |
93 | } | 92 | } |
94 | 93 | ||
95 | static inline int fw_write(struct i2c_client *client, u8 * data, int size) | 94 | static int fw_write(struct i2c_client *client, u8 * data, int size) |
96 | { | 95 | { |
97 | if (i2c_master_send(client, data, size) < size) { | 96 | int sent; |
97 | |||
98 | if ((sent = i2c_master_send(client, data, size)) < size) { | ||
98 | 99 | ||
99 | if (fastfw) { | 100 | if (fastfw) { |
100 | cx25840_err("333MHz i2c firmware load failed\n"); | 101 | v4l_err(client, "333MHz i2c firmware load failed\n"); |
101 | fastfw = 0; | 102 | fastfw = 0; |
102 | set_i2c_delay(client, 10); | 103 | set_i2c_delay(client, 10); |
103 | 104 | ||
105 | if (sent > 2) { | ||
106 | u16 dl_addr = cx25840_read(client, 0x801) << 8; | ||
107 | dl_addr |= cx25840_read(client, 0x800); | ||
108 | dl_addr -= sent - 2; | ||
109 | cx25840_write(client, 0x801, dl_addr >> 8); | ||
110 | cx25840_write(client, 0x800, dl_addr & 0xff); | ||
111 | } | ||
112 | |||
104 | if (i2c_master_send(client, data, size) < size) { | 113 | if (i2c_master_send(client, data, size) < size) { |
105 | cx25840_err | 114 | v4l_err(client, "100MHz i2c firmware load failed\n"); |
106 | ("100MHz i2c firmware load failed\n"); | ||
107 | return -ENOSYS; | 115 | return -ENOSYS; |
108 | } | 116 | } |
109 | 117 | ||
110 | } else { | 118 | } else { |
111 | cx25840_err("firmware load i2c failure\n"); | 119 | v4l_err(client, "firmware load i2c failure\n"); |
112 | return -ENOSYS; | 120 | return -ENOSYS; |
113 | } | 121 | } |
114 | 122 | ||
@@ -124,7 +132,7 @@ int cx25840_loadfw(struct i2c_client *client) | |||
124 | int size, send, retval; | 132 | int size, send, retval; |
125 | 133 | ||
126 | if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { | 134 | if (request_firmware(&fw, firmware, FWDEV(client)) != 0) { |
127 | cx25840_err("unable to open firmware %s\n", firmware); | 135 | v4l_err(client, "unable to open firmware %s\n", firmware); |
128 | return -EINVAL; | 136 | return -EINVAL; |
129 | } | 137 | } |
130 | 138 | ||