diff options
author | Olivier Grenie <olivier.grenie@dibcom.fr> | 2011-05-03 11:27:33 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-20 08:30:52 -0400 |
commit | 5a0deeed5741117ee8625d6305d0034e219f102c (patch) | |
tree | 2073570031d4ea19d0acacd5248f8e425fb019fa /drivers/media/dvb | |
parent | 027e99abbfdcca2ed46dfe4ea27c7cc253648cef (diff) |
[media] DiBxxxx: get rid of DMA buffer on stack
This patch removes the remaining on-stack buffer for USB DMA transfer.
This patch also reduces the stack memory usage.
Cc: stable@kernel.org
Cc: Florian Mickler <florian@mickler.org>
Signed-off-by: Olivier Grenie <olivier.grenie@dibcom.fr>
Signed-off-by: Patrick Boettcher <patrick.boettcher@dibcom.fr>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb')
-rw-r--r-- | drivers/media/dvb/frontends/dib0070.c | 40 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib0090.c | 71 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib7000m.c | 49 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib7000p.c | 72 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib8000.c | 126 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dib9000.c | 172 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dibx000_common.c | 109 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/dibx000_common.h | 5 |
8 files changed, 443 insertions, 201 deletions
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c index d4e466a90e43..1d47d4da7d4c 100644 --- a/drivers/media/dvb/frontends/dib0070.c +++ b/drivers/media/dvb/frontends/dib0070.c | |||
@@ -73,27 +73,47 @@ struct dib0070_state { | |||
73 | 73 | ||
74 | u8 wbd_gain_current; | 74 | u8 wbd_gain_current; |
75 | u16 wbd_offset_3_3[2]; | 75 | u16 wbd_offset_3_3[2]; |
76 | |||
77 | /* for the I2C transfer */ | ||
78 | struct i2c_msg msg[2]; | ||
79 | u8 i2c_write_buffer[3]; | ||
80 | u8 i2c_read_buffer[2]; | ||
76 | }; | 81 | }; |
77 | 82 | ||
78 | static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) | 83 | static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) |
79 | { | 84 | { |
80 | u8 b[2]; | 85 | state->i2c_write_buffer[0] = reg; |
81 | struct i2c_msg msg[2] = { | 86 | |
82 | { .addr = state->cfg->i2c_address, .flags = 0, .buf = ®, .len = 1 }, | 87 | memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); |
83 | { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, | 88 | state->msg[0].addr = state->cfg->i2c_address; |
84 | }; | 89 | state->msg[0].flags = 0; |
85 | if (i2c_transfer(state->i2c, msg, 2) != 2) { | 90 | state->msg[0].buf = state->i2c_write_buffer; |
91 | state->msg[0].len = 1; | ||
92 | state->msg[1].addr = state->cfg->i2c_address; | ||
93 | state->msg[1].flags = I2C_M_RD; | ||
94 | state->msg[1].buf = state->i2c_read_buffer; | ||
95 | state->msg[1].len = 2; | ||
96 | |||
97 | if (i2c_transfer(state->i2c, state->msg, 2) != 2) { | ||
86 | printk(KERN_WARNING "DiB0070 I2C read failed\n"); | 98 | printk(KERN_WARNING "DiB0070 I2C read failed\n"); |
87 | return 0; | 99 | return 0; |
88 | } | 100 | } |
89 | return (b[0] << 8) | b[1]; | 101 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; |
90 | } | 102 | } |
91 | 103 | ||
92 | static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) | 104 | static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) |
93 | { | 105 | { |
94 | u8 b[3] = { reg, val >> 8, val & 0xff }; | 106 | state->i2c_write_buffer[0] = reg; |
95 | struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; | 107 | state->i2c_write_buffer[1] = val >> 8; |
96 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | 108 | state->i2c_write_buffer[2] = val & 0xff; |
109 | |||
110 | memset(state->msg, 0, sizeof(struct i2c_msg)); | ||
111 | state->msg[0].addr = state->cfg->i2c_address; | ||
112 | state->msg[0].flags = 0; | ||
113 | state->msg[0].buf = state->i2c_write_buffer; | ||
114 | state->msg[0].len = 3; | ||
115 | |||
116 | if (i2c_transfer(state->i2c, state->msg, 1) != 1) { | ||
97 | printk(KERN_WARNING "DiB0070 I2C write failed\n"); | 117 | printk(KERN_WARNING "DiB0070 I2C write failed\n"); |
98 | return -EREMOTEIO; | 118 | return -EREMOTEIO; |
99 | } | 119 | } |
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c index 52ff1a252a90..c9c935ae41e4 100644 --- a/drivers/media/dvb/frontends/dib0090.c +++ b/drivers/media/dvb/frontends/dib0090.c | |||
@@ -191,6 +191,11 @@ struct dib0090_state { | |||
191 | u8 wbd_calibration_gain; | 191 | u8 wbd_calibration_gain; |
192 | const struct dib0090_wbd_slope *current_wbd_table; | 192 | const struct dib0090_wbd_slope *current_wbd_table; |
193 | u16 wbdmux; | 193 | u16 wbdmux; |
194 | |||
195 | /* for the I2C transfer */ | ||
196 | struct i2c_msg msg[2]; | ||
197 | u8 i2c_write_buffer[3]; | ||
198 | u8 i2c_read_buffer[2]; | ||
194 | }; | 199 | }; |
195 | 200 | ||
196 | struct dib0090_fw_state { | 201 | struct dib0090_fw_state { |
@@ -198,27 +203,48 @@ struct dib0090_fw_state { | |||
198 | struct dvb_frontend *fe; | 203 | struct dvb_frontend *fe; |
199 | struct dib0090_identity identity; | 204 | struct dib0090_identity identity; |
200 | const struct dib0090_config *config; | 205 | const struct dib0090_config *config; |
206 | |||
207 | /* for the I2C transfer */ | ||
208 | struct i2c_msg msg; | ||
209 | u8 i2c_write_buffer[2]; | ||
210 | u8 i2c_read_buffer[2]; | ||
201 | }; | 211 | }; |
202 | 212 | ||
203 | static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) | 213 | static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) |
204 | { | 214 | { |
205 | u8 b[2]; | 215 | state->i2c_write_buffer[0] = reg; |
206 | struct i2c_msg msg[2] = { | 216 | |
207 | {.addr = state->config->i2c_address, .flags = 0, .buf = ®, .len = 1}, | 217 | memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); |
208 | {.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2}, | 218 | state->msg[0].addr = state->config->i2c_address; |
209 | }; | 219 | state->msg[0].flags = 0; |
210 | if (i2c_transfer(state->i2c, msg, 2) != 2) { | 220 | state->msg[0].buf = state->i2c_write_buffer; |
221 | state->msg[0].len = 1; | ||
222 | state->msg[1].addr = state->config->i2c_address; | ||
223 | state->msg[1].flags = I2C_M_RD; | ||
224 | state->msg[1].buf = state->i2c_read_buffer; | ||
225 | state->msg[1].len = 2; | ||
226 | |||
227 | if (i2c_transfer(state->i2c, state->msg, 2) != 2) { | ||
211 | printk(KERN_WARNING "DiB0090 I2C read failed\n"); | 228 | printk(KERN_WARNING "DiB0090 I2C read failed\n"); |
212 | return 0; | 229 | return 0; |
213 | } | 230 | } |
214 | return (b[0] << 8) | b[1]; | 231 | |
232 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; | ||
215 | } | 233 | } |
216 | 234 | ||
217 | static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) | 235 | static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) |
218 | { | 236 | { |
219 | u8 b[3] = { reg & 0xff, val >> 8, val & 0xff }; | 237 | state->i2c_write_buffer[0] = reg & 0xff; |
220 | struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 }; | 238 | state->i2c_write_buffer[1] = val >> 8; |
221 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | 239 | state->i2c_write_buffer[2] = val & 0xff; |
240 | |||
241 | memset(state->msg, 0, sizeof(struct i2c_msg)); | ||
242 | state->msg[0].addr = state->config->i2c_address; | ||
243 | state->msg[0].flags = 0; | ||
244 | state->msg[0].buf = state->i2c_write_buffer; | ||
245 | state->msg[0].len = 3; | ||
246 | |||
247 | if (i2c_transfer(state->i2c, state->msg, 1) != 1) { | ||
222 | printk(KERN_WARNING "DiB0090 I2C write failed\n"); | 248 | printk(KERN_WARNING "DiB0090 I2C write failed\n"); |
223 | return -EREMOTEIO; | 249 | return -EREMOTEIO; |
224 | } | 250 | } |
@@ -227,20 +253,31 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) | |||
227 | 253 | ||
228 | static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) | 254 | static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) |
229 | { | 255 | { |
230 | u8 b[2]; | 256 | state->i2c_write_buffer[0] = reg; |
231 | struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 }; | 257 | |
232 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | 258 | memset(&state->msg, 0, sizeof(struct i2c_msg)); |
259 | state->msg.addr = reg; | ||
260 | state->msg.flags = I2C_M_RD; | ||
261 | state->msg.buf = state->i2c_read_buffer; | ||
262 | state->msg.len = 2; | ||
263 | if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { | ||
233 | printk(KERN_WARNING "DiB0090 I2C read failed\n"); | 264 | printk(KERN_WARNING "DiB0090 I2C read failed\n"); |
234 | return 0; | 265 | return 0; |
235 | } | 266 | } |
236 | return (b[0] << 8) | b[1]; | 267 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; |
237 | } | 268 | } |
238 | 269 | ||
239 | static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) | 270 | static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) |
240 | { | 271 | { |
241 | u8 b[2] = { val >> 8, val & 0xff }; | 272 | state->i2c_write_buffer[0] = val >> 8; |
242 | struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 }; | 273 | state->i2c_write_buffer[1] = val & 0xff; |
243 | if (i2c_transfer(state->i2c, &msg, 1) != 1) { | 274 | |
275 | memset(&state->msg, 0, sizeof(struct i2c_msg)); | ||
276 | state->msg.addr = reg; | ||
277 | state->msg.flags = 0; | ||
278 | state->msg.buf = state->i2c_write_buffer; | ||
279 | state->msg.len = 2; | ||
280 | if (i2c_transfer(state->i2c, &state->msg, 1) != 1) { | ||
244 | printk(KERN_WARNING "DiB0090 I2C write failed\n"); | 281 | printk(KERN_WARNING "DiB0090 I2C write failed\n"); |
245 | return -EREMOTEIO; | 282 | return -EREMOTEIO; |
246 | } | 283 | } |
diff --git a/drivers/media/dvb/frontends/dib7000m.c b/drivers/media/dvb/frontends/dib7000m.c index 289a79837f24..79cb1c20df24 100644 --- a/drivers/media/dvb/frontends/dib7000m.c +++ b/drivers/media/dvb/frontends/dib7000m.c | |||
@@ -50,6 +50,11 @@ struct dib7000m_state { | |||
50 | u16 revision; | 50 | u16 revision; |
51 | 51 | ||
52 | u8 agc_state; | 52 | u8 agc_state; |
53 | |||
54 | /* for the I2C transfer */ | ||
55 | struct i2c_msg msg[2]; | ||
56 | u8 i2c_write_buffer[4]; | ||
57 | u8 i2c_read_buffer[2]; | ||
53 | }; | 58 | }; |
54 | 59 | ||
55 | enum dib7000m_power_mode { | 60 | enum dib7000m_power_mode { |
@@ -64,29 +69,39 @@ enum dib7000m_power_mode { | |||
64 | 69 | ||
65 | static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) | 70 | static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) |
66 | { | 71 | { |
67 | u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; | 72 | state->i2c_write_buffer[0] = (reg >> 8) | 0x80; |
68 | u8 rb[2]; | 73 | state->i2c_write_buffer[1] = reg & 0xff; |
69 | struct i2c_msg msg[2] = { | 74 | |
70 | { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, | 75 | memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); |
71 | { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, | 76 | state->msg[0].addr = state->i2c_addr >> 1; |
72 | }; | 77 | state->msg[0].flags = 0; |
73 | 78 | state->msg[0].buf = state->i2c_write_buffer; | |
74 | if (i2c_transfer(state->i2c_adap, msg, 2) != 2) | 79 | state->msg[0].len = 2; |
80 | state->msg[1].addr = state->i2c_addr >> 1; | ||
81 | state->msg[1].flags = I2C_M_RD; | ||
82 | state->msg[1].buf = state->i2c_read_buffer; | ||
83 | state->msg[1].len = 2; | ||
84 | |||
85 | if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2) | ||
75 | dprintk("i2c read error on %d",reg); | 86 | dprintk("i2c read error on %d",reg); |
76 | 87 | ||
77 | return (rb[0] << 8) | rb[1]; | 88 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; |
78 | } | 89 | } |
79 | 90 | ||
80 | static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val) | 91 | static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val) |
81 | { | 92 | { |
82 | u8 b[4] = { | 93 | state->i2c_write_buffer[0] = (reg >> 8) & 0xff; |
83 | (reg >> 8) & 0xff, reg & 0xff, | 94 | state->i2c_write_buffer[1] = reg & 0xff; |
84 | (val >> 8) & 0xff, val & 0xff, | 95 | state->i2c_write_buffer[2] = (val >> 8) & 0xff; |
85 | }; | 96 | state->i2c_write_buffer[3] = val & 0xff; |
86 | struct i2c_msg msg = { | 97 | |
87 | .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 | 98 | memset(&state->msg[0], 0, sizeof(struct i2c_msg)); |
88 | }; | 99 | state->msg[0].addr = state->i2c_addr >> 1; |
89 | return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; | 100 | state->msg[0].flags = 0; |
101 | state->msg[0].buf = state->i2c_write_buffer; | ||
102 | state->msg[0].len = 4; | ||
103 | |||
104 | return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0; | ||
90 | } | 105 | } |
91 | static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf) | 106 | static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf) |
92 | { | 107 | { |
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c index 900af60b9d36..0c9f40c2a251 100644 --- a/drivers/media/dvb/frontends/dib7000p.c +++ b/drivers/media/dvb/frontends/dib7000p.c | |||
@@ -63,6 +63,11 @@ struct dib7000p_state { | |||
63 | 63 | ||
64 | u16 tuner_enable; | 64 | u16 tuner_enable; |
65 | struct i2c_adapter dib7090_tuner_adap; | 65 | struct i2c_adapter dib7090_tuner_adap; |
66 | |||
67 | /* for the I2C transfer */ | ||
68 | struct i2c_msg msg[2]; | ||
69 | u8 i2c_write_buffer[4]; | ||
70 | u8 i2c_read_buffer[2]; | ||
66 | }; | 71 | }; |
67 | 72 | ||
68 | enum dib7000p_power_mode { | 73 | enum dib7000p_power_mode { |
@@ -76,29 +81,39 @@ static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); | |||
76 | 81 | ||
77 | static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) | 82 | static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) |
78 | { | 83 | { |
79 | u8 wb[2] = { reg >> 8, reg & 0xff }; | 84 | state->i2c_write_buffer[0] = reg >> 8; |
80 | u8 rb[2]; | 85 | state->i2c_write_buffer[1] = reg & 0xff; |
81 | struct i2c_msg msg[2] = { | 86 | |
82 | {.addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2}, | 87 | memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); |
83 | {.addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2}, | 88 | state->msg[0].addr = state->i2c_addr >> 1; |
84 | }; | 89 | state->msg[0].flags = 0; |
90 | state->msg[0].buf = state->i2c_write_buffer; | ||
91 | state->msg[0].len = 2; | ||
92 | state->msg[1].addr = state->i2c_addr >> 1; | ||
93 | state->msg[1].flags = I2C_M_RD; | ||
94 | state->msg[1].buf = state->i2c_read_buffer; | ||
95 | state->msg[1].len = 2; | ||
85 | 96 | ||
86 | if (i2c_transfer(state->i2c_adap, msg, 2) != 2) | 97 | if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2) |
87 | dprintk("i2c read error on %d", reg); | 98 | dprintk("i2c read error on %d", reg); |
88 | 99 | ||
89 | return (rb[0] << 8) | rb[1]; | 100 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; |
90 | } | 101 | } |
91 | 102 | ||
92 | static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) | 103 | static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) |
93 | { | 104 | { |
94 | u8 b[4] = { | 105 | state->i2c_write_buffer[0] = (reg >> 8) & 0xff; |
95 | (reg >> 8) & 0xff, reg & 0xff, | 106 | state->i2c_write_buffer[1] = reg & 0xff; |
96 | (val >> 8) & 0xff, val & 0xff, | 107 | state->i2c_write_buffer[2] = (val >> 8) & 0xff; |
97 | }; | 108 | state->i2c_write_buffer[3] = val & 0xff; |
98 | struct i2c_msg msg = { | 109 | |
99 | .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 | 110 | memset(&state->msg[0], 0, sizeof(struct i2c_msg)); |
100 | }; | 111 | state->msg[0].addr = state->i2c_addr >> 1; |
101 | return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; | 112 | state->msg[0].flags = 0; |
113 | state->msg[0].buf = state->i2c_write_buffer; | ||
114 | state->msg[0].len = 4; | ||
115 | |||
116 | return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0; | ||
102 | } | 117 | } |
103 | 118 | ||
104 | static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf) | 119 | static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf) |
@@ -1550,11 +1565,24 @@ static void dib7000p_release(struct dvb_frontend *demod) | |||
1550 | 1565 | ||
1551 | int dib7000pc_detection(struct i2c_adapter *i2c_adap) | 1566 | int dib7000pc_detection(struct i2c_adapter *i2c_adap) |
1552 | { | 1567 | { |
1553 | u8 tx[2], rx[2]; | 1568 | u8 *tx, *rx; |
1554 | struct i2c_msg msg[2] = { | 1569 | struct i2c_msg msg[2] = { |
1555 | {.addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2}, | 1570 | {.addr = 18 >> 1, .flags = 0, .len = 2}, |
1556 | {.addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2}, | 1571 | {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2}, |
1557 | }; | 1572 | }; |
1573 | int ret = 0; | ||
1574 | |||
1575 | tx = kzalloc(2*sizeof(u8), GFP_KERNEL); | ||
1576 | if (!tx) | ||
1577 | return -ENOMEM; | ||
1578 | rx = kzalloc(2*sizeof(u8), GFP_KERNEL); | ||
1579 | if (!rx) { | ||
1580 | goto rx_memory_error; | ||
1581 | ret = -ENOMEM; | ||
1582 | } | ||
1583 | |||
1584 | msg[0].buf = tx; | ||
1585 | msg[1].buf = rx; | ||
1558 | 1586 | ||
1559 | tx[0] = 0x03; | 1587 | tx[0] = 0x03; |
1560 | tx[1] = 0x00; | 1588 | tx[1] = 0x00; |
@@ -1574,7 +1602,11 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap) | |||
1574 | } | 1602 | } |
1575 | 1603 | ||
1576 | dprintk("-D- DiB7000PC not detected"); | 1604 | dprintk("-D- DiB7000PC not detected"); |
1577 | return 0; | 1605 | |
1606 | kfree(rx); | ||
1607 | rx_memory_error: | ||
1608 | kfree(tx); | ||
1609 | return ret; | ||
1578 | } | 1610 | } |
1579 | EXPORT_SYMBOL(dib7000pc_detection); | 1611 | EXPORT_SYMBOL(dib7000pc_detection); |
1580 | 1612 | ||
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c index c1c3e26906e2..7d2ea112ae2b 100644 --- a/drivers/media/dvb/frontends/dib8000.c +++ b/drivers/media/dvb/frontends/dib8000.c | |||
@@ -35,6 +35,8 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); | |||
35 | struct i2c_device { | 35 | struct i2c_device { |
36 | struct i2c_adapter *adap; | 36 | struct i2c_adapter *adap; |
37 | u8 addr; | 37 | u8 addr; |
38 | u8 *i2c_write_buffer; | ||
39 | u8 *i2c_read_buffer; | ||
38 | }; | 40 | }; |
39 | 41 | ||
40 | struct dib8000_state { | 42 | struct dib8000_state { |
@@ -70,6 +72,11 @@ struct dib8000_state { | |||
70 | u32 status; | 72 | u32 status; |
71 | 73 | ||
72 | struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; | 74 | struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; |
75 | |||
76 | /* for the I2C transfer */ | ||
77 | struct i2c_msg msg[2]; | ||
78 | u8 i2c_write_buffer[4]; | ||
79 | u8 i2c_read_buffer[2]; | ||
73 | }; | 80 | }; |
74 | 81 | ||
75 | enum dib8000_power_mode { | 82 | enum dib8000_power_mode { |
@@ -79,22 +86,41 @@ enum dib8000_power_mode { | |||
79 | 86 | ||
80 | static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) | 87 | static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) |
81 | { | 88 | { |
82 | u8 wb[2] = { reg >> 8, reg & 0xff }; | ||
83 | u8 rb[2]; | ||
84 | struct i2c_msg msg[2] = { | 89 | struct i2c_msg msg[2] = { |
85 | {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2}, | 90 | {.addr = i2c->addr >> 1, .flags = 0, |
86 | {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2}, | 91 | .buf = i2c->i2c_write_buffer, .len = 2}, |
92 | {.addr = i2c->addr >> 1, .flags = I2C_M_RD, | ||
93 | .buf = i2c->i2c_read_buffer, .len = 2}, | ||
87 | }; | 94 | }; |
88 | 95 | ||
96 | msg[0].buf[0] = reg >> 8; | ||
97 | msg[0].buf[1] = reg & 0xff; | ||
98 | |||
89 | if (i2c_transfer(i2c->adap, msg, 2) != 2) | 99 | if (i2c_transfer(i2c->adap, msg, 2) != 2) |
90 | dprintk("i2c read error on %d", reg); | 100 | dprintk("i2c read error on %d", reg); |
91 | 101 | ||
92 | return (rb[0] << 8) | rb[1]; | 102 | return (msg[1].buf[0] << 8) | msg[1].buf[1]; |
93 | } | 103 | } |
94 | 104 | ||
95 | static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) | 105 | static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) |
96 | { | 106 | { |
97 | return dib8000_i2c_read16(&state->i2c, reg); | 107 | state->i2c_write_buffer[0] = reg >> 8; |
108 | state->i2c_write_buffer[1] = reg & 0xff; | ||
109 | |||
110 | memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); | ||
111 | state->msg[0].addr = state->i2c.addr >> 1; | ||
112 | state->msg[0].flags = 0; | ||
113 | state->msg[0].buf = state->i2c_write_buffer; | ||
114 | state->msg[0].len = 2; | ||
115 | state->msg[1].addr = state->i2c.addr >> 1; | ||
116 | state->msg[1].flags = I2C_M_RD; | ||
117 | state->msg[1].buf = state->i2c_read_buffer; | ||
118 | state->msg[1].len = 2; | ||
119 | |||
120 | if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2) | ||
121 | dprintk("i2c read error on %d", reg); | ||
122 | |||
123 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; | ||
98 | } | 124 | } |
99 | 125 | ||
100 | static u32 dib8000_read32(struct dib8000_state *state, u16 reg) | 126 | static u32 dib8000_read32(struct dib8000_state *state, u16 reg) |
@@ -109,19 +135,34 @@ static u32 dib8000_read32(struct dib8000_state *state, u16 reg) | |||
109 | 135 | ||
110 | static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) | 136 | static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) |
111 | { | 137 | { |
112 | u8 b[4] = { | 138 | struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0, |
113 | (reg >> 8) & 0xff, reg & 0xff, | 139 | .buf = i2c->i2c_write_buffer, .len = 4}; |
114 | (val >> 8) & 0xff, val & 0xff, | 140 | int ret = 0; |
115 | }; | 141 | |
116 | struct i2c_msg msg = { | 142 | msg.buf[0] = (reg >> 8) & 0xff; |
117 | .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4 | 143 | msg.buf[1] = reg & 0xff; |
118 | }; | 144 | msg.buf[2] = (val >> 8) & 0xff; |
119 | return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0; | 145 | msg.buf[3] = val & 0xff; |
146 | |||
147 | ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0; | ||
148 | |||
149 | return ret; | ||
120 | } | 150 | } |
121 | 151 | ||
122 | static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) | 152 | static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) |
123 | { | 153 | { |
124 | return dib8000_i2c_write16(&state->i2c, reg, val); | 154 | state->i2c_write_buffer[0] = (reg >> 8) & 0xff; |
155 | state->i2c_write_buffer[1] = reg & 0xff; | ||
156 | state->i2c_write_buffer[2] = (val >> 8) & 0xff; | ||
157 | state->i2c_write_buffer[3] = val & 0xff; | ||
158 | |||
159 | memset(&state->msg[0], 0, sizeof(struct i2c_msg)); | ||
160 | state->msg[0].addr = state->i2c.addr >> 1; | ||
161 | state->msg[0].flags = 0; | ||
162 | state->msg[0].buf = state->i2c_write_buffer; | ||
163 | state->msg[0].len = 4; | ||
164 | |||
165 | return i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? -EREMOTEIO : 0; | ||
125 | } | 166 | } |
126 | 167 | ||
127 | static const s16 coeff_2k_sb_1seg_dqpsk[8] = { | 168 | static const s16 coeff_2k_sb_1seg_dqpsk[8] = { |
@@ -980,30 +1021,31 @@ static void dib8000_update_timf(struct dib8000_state *state) | |||
980 | dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); | 1021 | dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); |
981 | } | 1022 | } |
982 | 1023 | ||
1024 | static const u16 adc_target_16dB[11] = { | ||
1025 | (1 << 13) - 825 - 117, | ||
1026 | (1 << 13) - 837 - 117, | ||
1027 | (1 << 13) - 811 - 117, | ||
1028 | (1 << 13) - 766 - 117, | ||
1029 | (1 << 13) - 737 - 117, | ||
1030 | (1 << 13) - 693 - 117, | ||
1031 | (1 << 13) - 648 - 117, | ||
1032 | (1 << 13) - 619 - 117, | ||
1033 | (1 << 13) - 575 - 117, | ||
1034 | (1 << 13) - 531 - 117, | ||
1035 | (1 << 13) - 501 - 117 | ||
1036 | }; | ||
1037 | static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 }; | ||
1038 | |||
983 | static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching) | 1039 | static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching) |
984 | { | 1040 | { |
985 | u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0; | 1041 | u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0; |
986 | u8 guard, crate, constellation, timeI; | 1042 | u8 guard, crate, constellation, timeI; |
987 | u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 }; | ||
988 | u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled | 1043 | u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled |
989 | const s16 *ncoeff = NULL, *ana_fe; | 1044 | const s16 *ncoeff = NULL, *ana_fe; |
990 | u16 tmcc_pow = 0; | 1045 | u16 tmcc_pow = 0; |
991 | u16 coff_pow = 0x2800; | 1046 | u16 coff_pow = 0x2800; |
992 | u16 init_prbs = 0xfff; | 1047 | u16 init_prbs = 0xfff; |
993 | u16 ana_gain = 0; | 1048 | u16 ana_gain = 0; |
994 | u16 adc_target_16dB[11] = { | ||
995 | (1 << 13) - 825 - 117, | ||
996 | (1 << 13) - 837 - 117, | ||
997 | (1 << 13) - 811 - 117, | ||
998 | (1 << 13) - 766 - 117, | ||
999 | (1 << 13) - 737 - 117, | ||
1000 | (1 << 13) - 693 - 117, | ||
1001 | (1 << 13) - 648 - 117, | ||
1002 | (1 << 13) - 619 - 117, | ||
1003 | (1 << 13) - 575 - 117, | ||
1004 | (1 << 13) - 531 - 117, | ||
1005 | (1 << 13) - 501 - 117 | ||
1006 | }; | ||
1007 | 1049 | ||
1008 | if (state->ber_monitored_layer != LAYER_ALL) | 1050 | if (state->ber_monitored_layer != LAYER_ALL) |
1009 | dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); | 1051 | dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); |
@@ -2379,10 +2421,22 @@ EXPORT_SYMBOL(dib8000_get_slave_frontend); | |||
2379 | 2421 | ||
2380 | int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) | 2422 | int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) |
2381 | { | 2423 | { |
2382 | int k = 0; | 2424 | int k = 0, ret = 0; |
2383 | u8 new_addr = 0; | 2425 | u8 new_addr = 0; |
2384 | struct i2c_device client = {.adap = host }; | 2426 | struct i2c_device client = {.adap = host }; |
2385 | 2427 | ||
2428 | client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); | ||
2429 | if (!client.i2c_write_buffer) { | ||
2430 | dprintk("%s: not enough memory", __func__); | ||
2431 | return -ENOMEM; | ||
2432 | } | ||
2433 | client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); | ||
2434 | if (!client.i2c_read_buffer) { | ||
2435 | dprintk("%s: not enough memory", __func__); | ||
2436 | ret = -ENOMEM; | ||
2437 | goto error_memory; | ||
2438 | } | ||
2439 | |||
2386 | for (k = no_of_demods - 1; k >= 0; k--) { | 2440 | for (k = no_of_demods - 1; k >= 0; k--) { |
2387 | /* designated i2c address */ | 2441 | /* designated i2c address */ |
2388 | new_addr = first_addr + (k << 1); | 2442 | new_addr = first_addr + (k << 1); |
@@ -2394,7 +2448,8 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau | |||
2394 | client.addr = default_addr; | 2448 | client.addr = default_addr; |
2395 | if (dib8000_identify(&client) == 0) { | 2449 | if (dib8000_identify(&client) == 0) { |
2396 | dprintk("#%d: not identified", k); | 2450 | dprintk("#%d: not identified", k); |
2397 | return -EINVAL; | 2451 | ret = -EINVAL; |
2452 | goto error; | ||
2398 | } | 2453 | } |
2399 | } | 2454 | } |
2400 | 2455 | ||
@@ -2420,7 +2475,12 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau | |||
2420 | dib8000_i2c_write16(&client, 1286, 0); | 2475 | dib8000_i2c_write16(&client, 1286, 0); |
2421 | } | 2476 | } |
2422 | 2477 | ||
2423 | return 0; | 2478 | error: |
2479 | kfree(client.i2c_read_buffer); | ||
2480 | error_memory: | ||
2481 | kfree(client.i2c_write_buffer); | ||
2482 | |||
2483 | return ret; | ||
2424 | } | 2484 | } |
2425 | 2485 | ||
2426 | EXPORT_SYMBOL(dib8000_i2c_enumeration); | 2486 | EXPORT_SYMBOL(dib8000_i2c_enumeration); |
@@ -2519,6 +2579,8 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s | |||
2519 | memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); | 2579 | memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); |
2520 | state->i2c.adap = i2c_adap; | 2580 | state->i2c.adap = i2c_adap; |
2521 | state->i2c.addr = i2c_addr; | 2581 | state->i2c.addr = i2c_addr; |
2582 | state->i2c.i2c_write_buffer = state->i2c_write_buffer; | ||
2583 | state->i2c.i2c_read_buffer = state->i2c_read_buffer; | ||
2522 | state->gpio_val = cfg->gpio_val; | 2584 | state->gpio_val = cfg->gpio_val; |
2523 | state->gpio_dir = cfg->gpio_dir; | 2585 | state->gpio_dir = cfg->gpio_dir; |
2524 | 2586 | ||
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c index b25ef2bb5078..a0855883b5ce 100644 --- a/drivers/media/dvb/frontends/dib9000.c +++ b/drivers/media/dvb/frontends/dib9000.c | |||
@@ -27,6 +27,8 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); | |||
27 | struct i2c_device { | 27 | struct i2c_device { |
28 | struct i2c_adapter *i2c_adap; | 28 | struct i2c_adapter *i2c_adap; |
29 | u8 i2c_addr; | 29 | u8 i2c_addr; |
30 | u8 *i2c_read_buffer; | ||
31 | u8 *i2c_write_buffer; | ||
30 | }; | 32 | }; |
31 | 33 | ||
32 | /* lock */ | 34 | /* lock */ |
@@ -92,11 +94,16 @@ struct dib9000_state { | |||
92 | 94 | ||
93 | struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; | 95 | struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; |
94 | u16 component_bus_speed; | 96 | u16 component_bus_speed; |
97 | |||
98 | /* for the I2C transfer */ | ||
99 | struct i2c_msg msg[2]; | ||
100 | u8 i2c_write_buffer[255]; | ||
101 | u8 i2c_read_buffer[255]; | ||
95 | }; | 102 | }; |
96 | 103 | ||
97 | u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 104 | static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
98 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 105 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
99 | 0, 0, 0 | 106 | 0, 0, 0, 0, 0, 0, 0, 0 |
100 | }; | 107 | }; |
101 | 108 | ||
102 | enum dib9000_power_mode { | 109 | enum dib9000_power_mode { |
@@ -217,25 +224,33 @@ static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32 | |||
217 | u32 chunk_size = 126; | 224 | u32 chunk_size = 126; |
218 | u32 l; | 225 | u32 l; |
219 | int ret; | 226 | int ret; |
220 | u8 wb[2] = { reg >> 8, reg & 0xff }; | ||
221 | struct i2c_msg msg[2] = { | ||
222 | {.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2}, | ||
223 | {.addr = state->i2c.i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = len}, | ||
224 | }; | ||
225 | 227 | ||
226 | if (state->platform.risc.fw_is_running && (reg < 1024)) | 228 | if (state->platform.risc.fw_is_running && (reg < 1024)) |
227 | return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len); | 229 | return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len); |
228 | 230 | ||
231 | memset(state->msg, 0, 2 * sizeof(struct i2c_msg)); | ||
232 | state->msg[0].addr = state->i2c.i2c_addr >> 1; | ||
233 | state->msg[0].flags = 0; | ||
234 | state->msg[0].buf = state->i2c_write_buffer; | ||
235 | state->msg[0].len = 2; | ||
236 | state->msg[1].addr = state->i2c.i2c_addr >> 1; | ||
237 | state->msg[1].flags = I2C_M_RD; | ||
238 | state->msg[1].buf = b; | ||
239 | state->msg[1].len = len; | ||
240 | |||
241 | state->i2c_write_buffer[0] = reg >> 8; | ||
242 | state->i2c_write_buffer[1] = reg & 0xff; | ||
243 | |||
229 | if (attribute & DATA_BUS_ACCESS_MODE_8BIT) | 244 | if (attribute & DATA_BUS_ACCESS_MODE_8BIT) |
230 | wb[0] |= (1 << 5); | 245 | state->i2c_write_buffer[0] |= (1 << 5); |
231 | if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT) | 246 | if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT) |
232 | wb[0] |= (1 << 4); | 247 | state->i2c_write_buffer[0] |= (1 << 4); |
233 | 248 | ||
234 | do { | 249 | do { |
235 | l = len < chunk_size ? len : chunk_size; | 250 | l = len < chunk_size ? len : chunk_size; |
236 | msg[1].len = l; | 251 | state->msg[1].len = l; |
237 | msg[1].buf = b; | 252 | state->msg[1].buf = b; |
238 | ret = i2c_transfer(state->i2c.i2c_adap, msg, 2) != 2 ? -EREMOTEIO : 0; | 253 | ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0; |
239 | if (ret != 0) { | 254 | if (ret != 0) { |
240 | dprintk("i2c read error on %d", reg); | 255 | dprintk("i2c read error on %d", reg); |
241 | return -EREMOTEIO; | 256 | return -EREMOTEIO; |
@@ -253,50 +268,47 @@ static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32 | |||
253 | 268 | ||
254 | static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg) | 269 | static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg) |
255 | { | 270 | { |
256 | u8 b[2]; | ||
257 | u8 wb[2] = { reg >> 8, reg & 0xff }; | ||
258 | struct i2c_msg msg[2] = { | 271 | struct i2c_msg msg[2] = { |
259 | {.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2}, | 272 | {.addr = i2c->i2c_addr >> 1, .flags = 0, |
260 | {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = 2}, | 273 | .buf = i2c->i2c_write_buffer, .len = 2}, |
274 | {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD, | ||
275 | .buf = i2c->i2c_read_buffer, .len = 2}, | ||
261 | }; | 276 | }; |
262 | 277 | ||
278 | i2c->i2c_write_buffer[0] = reg >> 8; | ||
279 | i2c->i2c_write_buffer[1] = reg & 0xff; | ||
280 | |||
263 | if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) { | 281 | if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) { |
264 | dprintk("read register %x error", reg); | 282 | dprintk("read register %x error", reg); |
265 | return 0; | 283 | return 0; |
266 | } | 284 | } |
267 | 285 | ||
268 | return (b[0] << 8) | b[1]; | 286 | return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1]; |
269 | } | 287 | } |
270 | 288 | ||
271 | static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg) | 289 | static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg) |
272 | { | 290 | { |
273 | u8 b[2]; | 291 | if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0) |
274 | if (dib9000_read16_attr(state, reg, b, 2, 0) != 0) | ||
275 | return 0; | 292 | return 0; |
276 | return (b[0] << 8 | b[1]); | 293 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; |
277 | } | 294 | } |
278 | 295 | ||
279 | static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute) | 296 | static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute) |
280 | { | 297 | { |
281 | u8 b[2]; | 298 | if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, |
282 | if (dib9000_read16_attr(state, reg, b, 2, attribute) != 0) | 299 | attribute) != 0) |
283 | return 0; | 300 | return 0; |
284 | return (b[0] << 8 | b[1]); | 301 | return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1]; |
285 | } | 302 | } |
286 | 303 | ||
287 | #define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT) | 304 | #define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT) |
288 | 305 | ||
289 | static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute) | 306 | static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute) |
290 | { | 307 | { |
291 | u8 b[255]; | ||
292 | u32 chunk_size = 126; | 308 | u32 chunk_size = 126; |
293 | u32 l; | 309 | u32 l; |
294 | int ret; | 310 | int ret; |
295 | 311 | ||
296 | struct i2c_msg msg = { | ||
297 | .addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = b, .len = len + 2 | ||
298 | }; | ||
299 | |||
300 | if (state->platform.risc.fw_is_running && (reg < 1024)) { | 312 | if (state->platform.risc.fw_is_running && (reg < 1024)) { |
301 | if (dib9000_risc_apb_access_write | 313 | if (dib9000_risc_apb_access_write |
302 | (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0) | 314 | (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0) |
@@ -304,20 +316,26 @@ static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * | |||
304 | return 0; | 316 | return 0; |
305 | } | 317 | } |
306 | 318 | ||
307 | b[0] = (reg >> 8) & 0xff; | 319 | memset(&state->msg[0], 0, sizeof(struct i2c_msg)); |
308 | b[1] = (reg) & 0xff; | 320 | state->msg[0].addr = state->i2c.i2c_addr >> 1; |
321 | state->msg[0].flags = 0; | ||
322 | state->msg[0].buf = state->i2c_write_buffer; | ||
323 | state->msg[0].len = len + 2; | ||
324 | |||
325 | state->i2c_write_buffer[0] = (reg >> 8) & 0xff; | ||
326 | state->i2c_write_buffer[1] = (reg) & 0xff; | ||
309 | 327 | ||
310 | if (attribute & DATA_BUS_ACCESS_MODE_8BIT) | 328 | if (attribute & DATA_BUS_ACCESS_MODE_8BIT) |
311 | b[0] |= (1 << 5); | 329 | state->i2c_write_buffer[0] |= (1 << 5); |
312 | if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT) | 330 | if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT) |
313 | b[0] |= (1 << 4); | 331 | state->i2c_write_buffer[0] |= (1 << 4); |
314 | 332 | ||
315 | do { | 333 | do { |
316 | l = len < chunk_size ? len : chunk_size; | 334 | l = len < chunk_size ? len : chunk_size; |
317 | msg.len = l + 2; | 335 | state->msg[0].len = l + 2; |
318 | memcpy(&b[2], buf, l); | 336 | memcpy(&state->i2c_write_buffer[2], buf, l); |
319 | 337 | ||
320 | ret = i2c_transfer(state->i2c.i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; | 338 | ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0; |
321 | 339 | ||
322 | buf += l; | 340 | buf += l; |
323 | len -= l; | 341 | len -= l; |
@@ -331,11 +349,16 @@ static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * | |||
331 | 349 | ||
332 | static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) | 350 | static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) |
333 | { | 351 | { |
334 | u8 b[4] = { (reg >> 8) & 0xff, reg & 0xff, (val >> 8) & 0xff, val & 0xff }; | ||
335 | struct i2c_msg msg = { | 352 | struct i2c_msg msg = { |
336 | .addr = i2c->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 | 353 | .addr = i2c->i2c_addr >> 1, .flags = 0, |
354 | .buf = i2c->i2c_write_buffer, .len = 4 | ||
337 | }; | 355 | }; |
338 | 356 | ||
357 | i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff; | ||
358 | i2c->i2c_write_buffer[1] = reg & 0xff; | ||
359 | i2c->i2c_write_buffer[2] = (val >> 8) & 0xff; | ||
360 | i2c->i2c_write_buffer[3] = val & 0xff; | ||
361 | |||
339 | return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; | 362 | return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; |
340 | } | 363 | } |
341 | 364 | ||
@@ -1015,8 +1038,8 @@ static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i) | |||
1015 | return 0; | 1038 | return 0; |
1016 | dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i); | 1039 | dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i); |
1017 | do { | 1040 | do { |
1018 | dib9000_risc_mem_read(state, FE_MM_RW_SYNC, &i, 1); | 1041 | dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1); |
1019 | } while (i && index_loop--); | 1042 | } while (state->i2c_read_buffer[0] && index_loop--); |
1020 | 1043 | ||
1021 | if (index_loop > 0) | 1044 | if (index_loop > 0) |
1022 | return 0; | 1045 | return 0; |
@@ -1139,7 +1162,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p | |||
1139 | 1162 | ||
1140 | s8 intlv_native; | 1163 | s8 intlv_native; |
1141 | }; | 1164 | }; |
1142 | struct dibDVBTChannel ch; | 1165 | struct dibDVBTChannel *ch; |
1143 | int ret = 0; | 1166 | int ret = 0; |
1144 | 1167 | ||
1145 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); | 1168 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); |
@@ -1148,9 +1171,12 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p | |||
1148 | ret = -EIO; | 1171 | ret = -EIO; |
1149 | } | 1172 | } |
1150 | 1173 | ||
1151 | dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, (u8 *) &ch, sizeof(struct dibDVBTChannel)); | 1174 | dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, |
1175 | state->i2c_read_buffer, sizeof(struct dibDVBTChannel)); | ||
1176 | ch = (struct dibDVBTChannel *)state->i2c_read_buffer; | ||
1177 | |||
1152 | 1178 | ||
1153 | switch (ch.spectrum_inversion & 0x7) { | 1179 | switch (ch->spectrum_inversion & 0x7) { |
1154 | case 1: | 1180 | case 1: |
1155 | state->fe[0]->dtv_property_cache.inversion = INVERSION_ON; | 1181 | state->fe[0]->dtv_property_cache.inversion = INVERSION_ON; |
1156 | break; | 1182 | break; |
@@ -1162,7 +1188,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p | |||
1162 | state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO; | 1188 | state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO; |
1163 | break; | 1189 | break; |
1164 | } | 1190 | } |
1165 | switch (ch.nfft) { | 1191 | switch (ch->nfft) { |
1166 | case 0: | 1192 | case 0: |
1167 | state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K; | 1193 | state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K; |
1168 | break; | 1194 | break; |
@@ -1177,7 +1203,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p | |||
1177 | state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO; | 1203 | state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO; |
1178 | break; | 1204 | break; |
1179 | } | 1205 | } |
1180 | switch (ch.guard) { | 1206 | switch (ch->guard) { |
1181 | case 0: | 1207 | case 0: |
1182 | state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32; | 1208 | state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32; |
1183 | break; | 1209 | break; |
@@ -1195,7 +1221,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p | |||
1195 | state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO; | 1221 | state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO; |
1196 | break; | 1222 | break; |
1197 | } | 1223 | } |
1198 | switch (ch.constellation) { | 1224 | switch (ch->constellation) { |
1199 | case 2: | 1225 | case 2: |
1200 | state->fe[0]->dtv_property_cache.modulation = QAM_64; | 1226 | state->fe[0]->dtv_property_cache.modulation = QAM_64; |
1201 | break; | 1227 | break; |
@@ -1210,7 +1236,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p | |||
1210 | state->fe[0]->dtv_property_cache.modulation = QAM_AUTO; | 1236 | state->fe[0]->dtv_property_cache.modulation = QAM_AUTO; |
1211 | break; | 1237 | break; |
1212 | } | 1238 | } |
1213 | switch (ch.hrch) { | 1239 | switch (ch->hrch) { |
1214 | case 0: | 1240 | case 0: |
1215 | state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE; | 1241 | state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE; |
1216 | break; | 1242 | break; |
@@ -1222,7 +1248,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p | |||
1222 | state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO; | 1248 | state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO; |
1223 | break; | 1249 | break; |
1224 | } | 1250 | } |
1225 | switch (ch.code_rate_hp) { | 1251 | switch (ch->code_rate_hp) { |
1226 | case 1: | 1252 | case 1: |
1227 | state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2; | 1253 | state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2; |
1228 | break; | 1254 | break; |
@@ -1243,7 +1269,7 @@ static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_p | |||
1243 | state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO; | 1269 | state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO; |
1244 | break; | 1270 | break; |
1245 | } | 1271 | } |
1246 | switch (ch.code_rate_lp) { | 1272 | switch (ch->code_rate_lp) { |
1247 | case 1: | 1273 | case 1: |
1248 | state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2; | 1274 | state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2; |
1249 | break; | 1275 | break; |
@@ -1439,9 +1465,10 @@ static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_paramete | |||
1439 | break; | 1465 | break; |
1440 | case CT_DEMOD_STEP_1: | 1466 | case CT_DEMOD_STEP_1: |
1441 | if (search) | 1467 | if (search) |
1442 | dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, (u8 *) &i, 1); | 1468 | dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1); |
1443 | else | 1469 | else |
1444 | dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, (u8 *) &i, 1); | 1470 | dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1); |
1471 | i = (s8)state->i2c_read_buffer[0]; | ||
1445 | switch (i) { /* something happened */ | 1472 | switch (i) { /* something happened */ |
1446 | case 0: | 1473 | case 0: |
1447 | break; | 1474 | break; |
@@ -2038,14 +2065,17 @@ static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat) | |||
2038 | static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber) | 2065 | static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber) |
2039 | { | 2066 | { |
2040 | struct dib9000_state *state = fe->demodulator_priv; | 2067 | struct dib9000_state *state = fe->demodulator_priv; |
2041 | u16 c[16]; | 2068 | u16 *c; |
2042 | 2069 | ||
2043 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); | 2070 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); |
2044 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) | 2071 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) |
2045 | return -EIO; | 2072 | return -EIO; |
2046 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c)); | 2073 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, |
2074 | state->i2c_read_buffer, 16 * 2); | ||
2047 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2075 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); |
2048 | 2076 | ||
2077 | c = (u16 *)state->i2c_read_buffer; | ||
2078 | |||
2049 | *ber = c[10] << 16 | c[11]; | 2079 | *ber = c[10] << 16 | c[11]; |
2050 | return 0; | 2080 | return 0; |
2051 | } | 2081 | } |
@@ -2054,7 +2084,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) | |||
2054 | { | 2084 | { |
2055 | struct dib9000_state *state = fe->demodulator_priv; | 2085 | struct dib9000_state *state = fe->demodulator_priv; |
2056 | u8 index_frontend; | 2086 | u8 index_frontend; |
2057 | u16 c[16]; | 2087 | u16 *c = (u16 *)state->i2c_read_buffer; |
2058 | u16 val; | 2088 | u16 val; |
2059 | 2089 | ||
2060 | *strength = 0; | 2090 | *strength = 0; |
@@ -2069,7 +2099,7 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) | |||
2069 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); | 2099 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); |
2070 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) | 2100 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) |
2071 | return -EIO; | 2101 | return -EIO; |
2072 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c)); | 2102 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); |
2073 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2103 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); |
2074 | 2104 | ||
2075 | val = 65535 - c[4]; | 2105 | val = 65535 - c[4]; |
@@ -2083,14 +2113,14 @@ static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) | |||
2083 | static u32 dib9000_get_snr(struct dvb_frontend *fe) | 2113 | static u32 dib9000_get_snr(struct dvb_frontend *fe) |
2084 | { | 2114 | { |
2085 | struct dib9000_state *state = fe->demodulator_priv; | 2115 | struct dib9000_state *state = fe->demodulator_priv; |
2086 | u16 c[16]; | 2116 | u16 *c = (u16 *)state->i2c_read_buffer; |
2087 | u32 n, s, exp; | 2117 | u32 n, s, exp; |
2088 | u16 val; | 2118 | u16 val; |
2089 | 2119 | ||
2090 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); | 2120 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); |
2091 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) | 2121 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) |
2092 | return -EIO; | 2122 | return -EIO; |
2093 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c)); | 2123 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); |
2094 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2124 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); |
2095 | 2125 | ||
2096 | val = c[7]; | 2126 | val = c[7]; |
@@ -2137,12 +2167,12 @@ static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr) | |||
2137 | static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) | 2167 | static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) |
2138 | { | 2168 | { |
2139 | struct dib9000_state *state = fe->demodulator_priv; | 2169 | struct dib9000_state *state = fe->demodulator_priv; |
2140 | u16 c[16]; | 2170 | u16 *c = (u16 *)state->i2c_read_buffer; |
2141 | 2171 | ||
2142 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); | 2172 | DibAcquireLock(&state->platform.risc.mem_mbx_lock); |
2143 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) | 2173 | if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) |
2144 | return -EIO; | 2174 | return -EIO; |
2145 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c)); | 2175 | dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2); |
2146 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); | 2176 | DibReleaseLock(&state->platform.risc.mem_mbx_lock); |
2147 | 2177 | ||
2148 | *unc = c[12]; | 2178 | *unc = c[12]; |
@@ -2151,10 +2181,22 @@ static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc) | |||
2151 | 2181 | ||
2152 | int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr) | 2182 | int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr) |
2153 | { | 2183 | { |
2154 | int k = 0; | 2184 | int k = 0, ret = 0; |
2155 | u8 new_addr = 0; | 2185 | u8 new_addr = 0; |
2156 | struct i2c_device client = {.i2c_adap = i2c }; | 2186 | struct i2c_device client = {.i2c_adap = i2c }; |
2157 | 2187 | ||
2188 | client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); | ||
2189 | if (!client.i2c_write_buffer) { | ||
2190 | dprintk("%s: not enough memory", __func__); | ||
2191 | return -ENOMEM; | ||
2192 | } | ||
2193 | client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL); | ||
2194 | if (!client.i2c_read_buffer) { | ||
2195 | dprintk("%s: not enough memory", __func__); | ||
2196 | ret = -ENOMEM; | ||
2197 | goto error_memory; | ||
2198 | } | ||
2199 | |||
2158 | client.i2c_addr = default_addr + 16; | 2200 | client.i2c_addr = default_addr + 16; |
2159 | dib9000_i2c_write16(&client, 1796, 0x0); | 2201 | dib9000_i2c_write16(&client, 1796, 0x0); |
2160 | 2202 | ||
@@ -2178,7 +2220,8 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul | |||
2178 | client.i2c_addr = default_addr; | 2220 | client.i2c_addr = default_addr; |
2179 | if (dib9000_identify(&client) == 0) { | 2221 | if (dib9000_identify(&client) == 0) { |
2180 | dprintk("DiB9000 #%d: not identified", k); | 2222 | dprintk("DiB9000 #%d: not identified", k); |
2181 | return -EIO; | 2223 | ret = -EIO; |
2224 | goto error; | ||
2182 | } | 2225 | } |
2183 | } | 2226 | } |
2184 | 2227 | ||
@@ -2196,7 +2239,12 @@ int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defaul | |||
2196 | dib9000_i2c_write16(&client, 1795, 0); | 2239 | dib9000_i2c_write16(&client, 1795, 0); |
2197 | } | 2240 | } |
2198 | 2241 | ||
2199 | return 0; | 2242 | error: |
2243 | kfree(client.i2c_read_buffer); | ||
2244 | error_memory: | ||
2245 | kfree(client.i2c_write_buffer); | ||
2246 | |||
2247 | return ret; | ||
2200 | } | 2248 | } |
2201 | EXPORT_SYMBOL(dib9000_i2c_enumeration); | 2249 | EXPORT_SYMBOL(dib9000_i2c_enumeration); |
2202 | 2250 | ||
@@ -2263,6 +2311,8 @@ struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, c | |||
2263 | memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config)); | 2311 | memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config)); |
2264 | st->i2c.i2c_adap = i2c_adap; | 2312 | st->i2c.i2c_adap = i2c_adap; |
2265 | st->i2c.i2c_addr = i2c_addr; | 2313 | st->i2c.i2c_addr = i2c_addr; |
2314 | st->i2c.i2c_write_buffer = st->i2c_write_buffer; | ||
2315 | st->i2c.i2c_read_buffer = st->i2c_read_buffer; | ||
2266 | 2316 | ||
2267 | st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS; | 2317 | st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS; |
2268 | st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES; | 2318 | st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES; |
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c index f6938f97feb4..dc5d17a67579 100644 --- a/drivers/media/dvb/frontends/dibx000_common.c +++ b/drivers/media/dvb/frontends/dibx000_common.c | |||
@@ -10,30 +10,39 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); | |||
10 | 10 | ||
11 | static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) | 11 | static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) |
12 | { | 12 | { |
13 | u8 b[4] = { | 13 | mst->i2c_write_buffer[0] = (reg >> 8) & 0xff; |
14 | (reg >> 8) & 0xff, reg & 0xff, | 14 | mst->i2c_write_buffer[1] = reg & 0xff; |
15 | (val >> 8) & 0xff, val & 0xff, | 15 | mst->i2c_write_buffer[2] = (val >> 8) & 0xff; |
16 | }; | 16 | mst->i2c_write_buffer[3] = val & 0xff; |
17 | struct i2c_msg msg = { | 17 | |
18 | .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4 | 18 | memset(mst->msg, 0, sizeof(struct i2c_msg)); |
19 | }; | 19 | mst->msg[0].addr = mst->i2c_addr; |
20 | 20 | mst->msg[0].flags = 0; | |
21 | return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; | 21 | mst->msg[0].buf = mst->i2c_write_buffer; |
22 | mst->msg[0].len = 4; | ||
23 | |||
24 | return i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0; | ||
22 | } | 25 | } |
23 | 26 | ||
24 | static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) | 27 | static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) |
25 | { | 28 | { |
26 | u8 wb[2] = { reg >> 8, reg & 0xff }; | 29 | mst->i2c_write_buffer[0] = reg >> 8; |
27 | u8 rb[2]; | 30 | mst->i2c_write_buffer[1] = reg & 0xff; |
28 | struct i2c_msg msg[2] = { | 31 | |
29 | {.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2}, | 32 | memset(mst->msg, 0, 2 * sizeof(struct i2c_msg)); |
30 | {.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2}, | 33 | mst->msg[0].addr = mst->i2c_addr; |
31 | }; | 34 | mst->msg[0].flags = 0; |
32 | 35 | mst->msg[0].buf = mst->i2c_write_buffer; | |
33 | if (i2c_transfer(mst->i2c_adap, msg, 2) != 2) | 36 | mst->msg[0].len = 2; |
37 | mst->msg[1].addr = mst->i2c_addr; | ||
38 | mst->msg[1].flags = I2C_M_RD; | ||
39 | mst->msg[1].buf = mst->i2c_read_buffer; | ||
40 | mst->msg[1].len = 2; | ||
41 | |||
42 | if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2) | ||
34 | dprintk("i2c read error on %d", reg); | 43 | dprintk("i2c read error on %d", reg); |
35 | 44 | ||
36 | return (rb[0] << 8) | rb[1]; | 45 | return (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1]; |
37 | } | 46 | } |
38 | 47 | ||
39 | static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst) | 48 | static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst) |
@@ -248,26 +257,32 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap, | |||
248 | struct i2c_msg msg[], int num) | 257 | struct i2c_msg msg[], int num) |
249 | { | 258 | { |
250 | struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); | 259 | struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); |
251 | struct i2c_msg m[2 + num]; | ||
252 | u8 tx_open[4], tx_close[4]; | ||
253 | 260 | ||
254 | memset(m, 0, sizeof(struct i2c_msg) * (2 + num)); | 261 | if (num > 32) { |
262 | dprintk("%s: too much I2C message to be transmitted (%i).\ | ||
263 | Maximum is 32", __func__, num); | ||
264 | return -ENOMEM; | ||
265 | } | ||
266 | |||
267 | memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num)); | ||
255 | 268 | ||
256 | dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7); | 269 | dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7); |
257 | 270 | ||
258 | dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); | 271 | /* open the gate */ |
259 | m[0].addr = mst->i2c_addr; | 272 | dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1); |
260 | m[0].buf = tx_open; | 273 | mst->msg[0].addr = mst->i2c_addr; |
261 | m[0].len = 4; | 274 | mst->msg[0].buf = &mst->i2c_write_buffer[0]; |
275 | mst->msg[0].len = 4; | ||
262 | 276 | ||
263 | memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); | 277 | memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num); |
264 | 278 | ||
265 | dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); | 279 | /* close the gate */ |
266 | m[num + 1].addr = mst->i2c_addr; | 280 | dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0); |
267 | m[num + 1].buf = tx_close; | 281 | mst->msg[num + 1].addr = mst->i2c_addr; |
268 | m[num + 1].len = 4; | 282 | mst->msg[num + 1].buf = &mst->i2c_write_buffer[4]; |
283 | mst->msg[num + 1].len = 4; | ||
269 | 284 | ||
270 | return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO; | 285 | return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO; |
271 | } | 286 | } |
272 | 287 | ||
273 | static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = { | 288 | static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = { |
@@ -279,26 +294,32 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, | |||
279 | struct i2c_msg msg[], int num) | 294 | struct i2c_msg msg[], int num) |
280 | { | 295 | { |
281 | struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); | 296 | struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); |
282 | struct i2c_msg m[2 + num]; | ||
283 | u8 tx_open[4], tx_close[4]; | ||
284 | 297 | ||
285 | memset(m, 0, sizeof(struct i2c_msg) * (2 + num)); | 298 | if (num > 32) { |
299 | dprintk("%s: too much I2C message to be transmitted (%i).\ | ||
300 | Maximum is 32", __func__, num); | ||
301 | return -ENOMEM; | ||
302 | } | ||
303 | |||
304 | memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num)); | ||
286 | 305 | ||
287 | dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); | 306 | dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); |
288 | 307 | ||
289 | dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); | 308 | /* open the gate */ |
290 | m[0].addr = mst->i2c_addr; | 309 | dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1); |
291 | m[0].buf = tx_open; | 310 | mst->msg[0].addr = mst->i2c_addr; |
292 | m[0].len = 4; | 311 | mst->msg[0].buf = &mst->i2c_write_buffer[0]; |
312 | mst->msg[0].len = 4; | ||
293 | 313 | ||
294 | memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); | 314 | memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num); |
295 | 315 | ||
296 | dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); | 316 | /* close the gate */ |
297 | m[num + 1].addr = mst->i2c_addr; | 317 | dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0); |
298 | m[num + 1].buf = tx_close; | 318 | mst->msg[num + 1].addr = mst->i2c_addr; |
299 | m[num + 1].len = 4; | 319 | mst->msg[num + 1].buf = &mst->i2c_write_buffer[4]; |
320 | mst->msg[num + 1].len = 4; | ||
300 | 321 | ||
301 | return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO; | 322 | return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO; |
302 | } | 323 | } |
303 | 324 | ||
304 | static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { | 325 | static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { |
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h index 977d343369aa..f031165c0459 100644 --- a/drivers/media/dvb/frontends/dibx000_common.h +++ b/drivers/media/dvb/frontends/dibx000_common.h | |||
@@ -28,6 +28,11 @@ struct dibx000_i2c_master { | |||
28 | u8 i2c_addr; | 28 | u8 i2c_addr; |
29 | 29 | ||
30 | u16 base_reg; | 30 | u16 base_reg; |
31 | |||
32 | /* for the I2C transfer */ | ||
33 | struct i2c_msg msg[34]; | ||
34 | u8 i2c_write_buffer[8]; | ||
35 | u8 i2c_read_buffer[2]; | ||
31 | }; | 36 | }; |
32 | 37 | ||
33 | extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, | 38 | extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, |