Commit 5a0deeed authored by Olivier Grenie's avatar Olivier Grenie Committed by Mauro Carvalho Chehab

[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: default avatarOlivier Grenie <olivier.grenie@dibcom.fr>
Signed-off-by: default avatarPatrick Boettcher <patrick.boettcher@dibcom.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 027e99ab
...@@ -73,27 +73,47 @@ struct dib0070_state { ...@@ -73,27 +73,47 @@ struct dib0070_state {
u8 wbd_gain_current; u8 wbd_gain_current;
u16 wbd_offset_3_3[2]; u16 wbd_offset_3_3[2];
/* for the I2C transfer */
struct i2c_msg msg[2];
u8 i2c_write_buffer[3];
u8 i2c_read_buffer[2];
}; };
static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
{ {
u8 b[2]; state->i2c_write_buffer[0] = reg;
struct i2c_msg msg[2] = {
{ .addr = state->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 }, memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
{ .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, state->msg[0].addr = state->cfg->i2c_address;
}; state->msg[0].flags = 0;
if (i2c_transfer(state->i2c, msg, 2) != 2) { state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 1;
state->msg[1].addr = state->cfg->i2c_address;
state->msg[1].flags = I2C_M_RD;
state->msg[1].buf = state->i2c_read_buffer;
state->msg[1].len = 2;
if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
printk(KERN_WARNING "DiB0070 I2C read failed\n"); printk(KERN_WARNING "DiB0070 I2C read failed\n");
return 0; return 0;
} }
return (b[0] << 8) | b[1]; return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
} }
static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
{ {
u8 b[3] = { reg, val >> 8, val & 0xff }; state->i2c_write_buffer[0] = reg;
struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; state->i2c_write_buffer[1] = val >> 8;
if (i2c_transfer(state->i2c, &msg, 1) != 1) { state->i2c_write_buffer[2] = val & 0xff;
memset(state->msg, 0, sizeof(struct i2c_msg));
state->msg[0].addr = state->cfg->i2c_address;
state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 3;
if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
printk(KERN_WARNING "DiB0070 I2C write failed\n"); printk(KERN_WARNING "DiB0070 I2C write failed\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
......
...@@ -191,6 +191,11 @@ struct dib0090_state { ...@@ -191,6 +191,11 @@ struct dib0090_state {
u8 wbd_calibration_gain; u8 wbd_calibration_gain;
const struct dib0090_wbd_slope *current_wbd_table; const struct dib0090_wbd_slope *current_wbd_table;
u16 wbdmux; u16 wbdmux;
/* for the I2C transfer */
struct i2c_msg msg[2];
u8 i2c_write_buffer[3];
u8 i2c_read_buffer[2];
}; };
struct dib0090_fw_state { struct dib0090_fw_state {
...@@ -198,27 +203,48 @@ struct dib0090_fw_state { ...@@ -198,27 +203,48 @@ struct dib0090_fw_state {
struct dvb_frontend *fe; struct dvb_frontend *fe;
struct dib0090_identity identity; struct dib0090_identity identity;
const struct dib0090_config *config; const struct dib0090_config *config;
/* for the I2C transfer */
struct i2c_msg msg;
u8 i2c_write_buffer[2];
u8 i2c_read_buffer[2];
}; };
static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
{ {
u8 b[2]; state->i2c_write_buffer[0] = reg;
struct i2c_msg msg[2] = {
{.addr = state->config->i2c_address, .flags = 0, .buf = &reg, .len = 1}, memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
{.addr = state->config->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2}, state->msg[0].addr = state->config->i2c_address;
}; state->msg[0].flags = 0;
if (i2c_transfer(state->i2c, msg, 2) != 2) { state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 1;
state->msg[1].addr = state->config->i2c_address;
state->msg[1].flags = I2C_M_RD;
state->msg[1].buf = state->i2c_read_buffer;
state->msg[1].len = 2;
if (i2c_transfer(state->i2c, state->msg, 2) != 2) {
printk(KERN_WARNING "DiB0090 I2C read failed\n"); printk(KERN_WARNING "DiB0090 I2C read failed\n");
return 0; return 0;
} }
return (b[0] << 8) | b[1];
return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
} }
static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
{ {
u8 b[3] = { reg & 0xff, val >> 8, val & 0xff }; state->i2c_write_buffer[0] = reg & 0xff;
struct i2c_msg msg = {.addr = state->config->i2c_address, .flags = 0, .buf = b, .len = 3 }; state->i2c_write_buffer[1] = val >> 8;
if (i2c_transfer(state->i2c, &msg, 1) != 1) { state->i2c_write_buffer[2] = val & 0xff;
memset(state->msg, 0, sizeof(struct i2c_msg));
state->msg[0].addr = state->config->i2c_address;
state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 3;
if (i2c_transfer(state->i2c, state->msg, 1) != 1) {
printk(KERN_WARNING "DiB0090 I2C write failed\n"); printk(KERN_WARNING "DiB0090 I2C write failed\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
...@@ -227,20 +253,31 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val) ...@@ -227,20 +253,31 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg) static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
{ {
u8 b[2]; state->i2c_write_buffer[0] = reg;
struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 };
if (i2c_transfer(state->i2c, &msg, 1) != 1) { memset(&state->msg, 0, sizeof(struct i2c_msg));
state->msg.addr = reg;
state->msg.flags = I2C_M_RD;
state->msg.buf = state->i2c_read_buffer;
state->msg.len = 2;
if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
printk(KERN_WARNING "DiB0090 I2C read failed\n"); printk(KERN_WARNING "DiB0090 I2C read failed\n");
return 0; return 0;
} }
return (b[0] << 8) | b[1]; return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
} }
static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val) static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
{ {
u8 b[2] = { val >> 8, val & 0xff }; state->i2c_write_buffer[0] = val >> 8;
struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 }; state->i2c_write_buffer[1] = val & 0xff;
if (i2c_transfer(state->i2c, &msg, 1) != 1) {
memset(&state->msg, 0, sizeof(struct i2c_msg));
state->msg.addr = reg;
state->msg.flags = 0;
state->msg.buf = state->i2c_write_buffer;
state->msg.len = 2;
if (i2c_transfer(state->i2c, &state->msg, 1) != 1) {
printk(KERN_WARNING "DiB0090 I2C write failed\n"); printk(KERN_WARNING "DiB0090 I2C write failed\n");
return -EREMOTEIO; return -EREMOTEIO;
} }
......
...@@ -50,6 +50,11 @@ struct dib7000m_state { ...@@ -50,6 +50,11 @@ struct dib7000m_state {
u16 revision; u16 revision;
u8 agc_state; u8 agc_state;
/* for the I2C transfer */
struct i2c_msg msg[2];
u8 i2c_write_buffer[4];
u8 i2c_read_buffer[2];
}; };
enum dib7000m_power_mode { enum dib7000m_power_mode {
...@@ -64,29 +69,39 @@ enum dib7000m_power_mode { ...@@ -64,29 +69,39 @@ enum dib7000m_power_mode {
static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg) static u16 dib7000m_read_word(struct dib7000m_state *state, u16 reg)
{ {
u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; state->i2c_write_buffer[0] = (reg >> 8) | 0x80;
u8 rb[2]; state->i2c_write_buffer[1] = reg & 0xff;
struct i2c_msg msg[2] = {
{ .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
{ .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, state->msg[0].addr = state->i2c_addr >> 1;
}; state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
if (i2c_transfer(state->i2c_adap, msg, 2) != 2) state->msg[0].len = 2;
state->msg[1].addr = state->i2c_addr >> 1;
state->msg[1].flags = I2C_M_RD;
state->msg[1].buf = state->i2c_read_buffer;
state->msg[1].len = 2;
if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
dprintk("i2c read error on %d",reg); dprintk("i2c read error on %d",reg);
return (rb[0] << 8) | rb[1]; return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
} }
static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val) static int dib7000m_write_word(struct dib7000m_state *state, u16 reg, u16 val)
{ {
u8 b[4] = { state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
(reg >> 8) & 0xff, reg & 0xff, state->i2c_write_buffer[1] = reg & 0xff;
(val >> 8) & 0xff, val & 0xff, state->i2c_write_buffer[2] = (val >> 8) & 0xff;
}; state->i2c_write_buffer[3] = val & 0xff;
struct i2c_msg msg = {
.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
}; state->msg[0].addr = state->i2c_addr >> 1;
return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 4;
return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
} }
static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf) static void dib7000m_write_tab(struct dib7000m_state *state, u16 *buf)
{ {
......
...@@ -63,6 +63,11 @@ struct dib7000p_state { ...@@ -63,6 +63,11 @@ struct dib7000p_state {
u16 tuner_enable; u16 tuner_enable;
struct i2c_adapter dib7090_tuner_adap; struct i2c_adapter dib7090_tuner_adap;
/* for the I2C transfer */
struct i2c_msg msg[2];
u8 i2c_write_buffer[4];
u8 i2c_read_buffer[2];
}; };
enum dib7000p_power_mode { enum dib7000p_power_mode {
...@@ -76,29 +81,39 @@ static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff); ...@@ -76,29 +81,39 @@ static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
{ {
u8 wb[2] = { reg >> 8, reg & 0xff }; state->i2c_write_buffer[0] = reg >> 8;
u8 rb[2]; state->i2c_write_buffer[1] = reg & 0xff;
struct i2c_msg msg[2] = {
{.addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2}, memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
{.addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2}, state->msg[0].addr = state->i2c_addr >> 1;
}; state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 2;
state->msg[1].addr = state->i2c_addr >> 1;
state->msg[1].flags = I2C_M_RD;
state->msg[1].buf = state->i2c_read_buffer;
state->msg[1].len = 2;
if (i2c_transfer(state->i2c_adap, msg, 2) != 2) if (i2c_transfer(state->i2c_adap, state->msg, 2) != 2)
dprintk("i2c read error on %d", reg); dprintk("i2c read error on %d", reg);
return (rb[0] << 8) | rb[1]; return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
} }
static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val) static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
{ {
u8 b[4] = { state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
(reg >> 8) & 0xff, reg & 0xff, state->i2c_write_buffer[1] = reg & 0xff;
(val >> 8) & 0xff, val & 0xff, state->i2c_write_buffer[2] = (val >> 8) & 0xff;
}; state->i2c_write_buffer[3] = val & 0xff;
struct i2c_msg msg = {
.addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
}; state->msg[0].addr = state->i2c_addr >> 1;
return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 4;
return i2c_transfer(state->i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
} }
static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf) static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
...@@ -1550,11 +1565,24 @@ static void dib7000p_release(struct dvb_frontend *demod) ...@@ -1550,11 +1565,24 @@ static void dib7000p_release(struct dvb_frontend *demod)
int dib7000pc_detection(struct i2c_adapter *i2c_adap) int dib7000pc_detection(struct i2c_adapter *i2c_adap)
{ {
u8 tx[2], rx[2]; u8 *tx, *rx;
struct i2c_msg msg[2] = { struct i2c_msg msg[2] = {
{.addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2}, {.addr = 18 >> 1, .flags = 0, .len = 2},
{.addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2}, {.addr = 18 >> 1, .flags = I2C_M_RD, .len = 2},
}; };
int ret = 0;
tx = kzalloc(2*sizeof(u8), GFP_KERNEL);
if (!tx)
return -ENOMEM;
rx = kzalloc(2*sizeof(u8), GFP_KERNEL);
if (!rx) {
goto rx_memory_error;
ret = -ENOMEM;
}
msg[0].buf = tx;
msg[1].buf = rx;
tx[0] = 0x03; tx[0] = 0x03;
tx[1] = 0x00; tx[1] = 0x00;
...@@ -1574,7 +1602,11 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap) ...@@ -1574,7 +1602,11 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
} }
dprintk("-D- DiB7000PC not detected"); dprintk("-D- DiB7000PC not detected");
return 0;
kfree(rx);
rx_memory_error:
kfree(tx);
return ret;
} }
EXPORT_SYMBOL(dib7000pc_detection); EXPORT_SYMBOL(dib7000pc_detection);
......
...@@ -35,6 +35,8 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); ...@@ -35,6 +35,8 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
struct i2c_device { struct i2c_device {
struct i2c_adapter *adap; struct i2c_adapter *adap;
u8 addr; u8 addr;
u8 *i2c_write_buffer;
u8 *i2c_read_buffer;
}; };
struct dib8000_state { struct dib8000_state {
...@@ -70,6 +72,11 @@ struct dib8000_state { ...@@ -70,6 +72,11 @@ struct dib8000_state {
u32 status; u32 status;
struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS]; struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
/* for the I2C transfer */
struct i2c_msg msg[2];
u8 i2c_write_buffer[4];
u8 i2c_read_buffer[2];
}; };
enum dib8000_power_mode { enum dib8000_power_mode {
...@@ -79,22 +86,41 @@ enum dib8000_power_mode { ...@@ -79,22 +86,41 @@ enum dib8000_power_mode {
static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg) static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
{ {
u8 wb[2] = { reg >> 8, reg & 0xff };
u8 rb[2];
struct i2c_msg msg[2] = { struct i2c_msg msg[2] = {
{.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2}, {.addr = i2c->addr >> 1, .flags = 0,
{.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2}, .buf = i2c->i2c_write_buffer, .len = 2},
{.addr = i2c->addr >> 1, .flags = I2C_M_RD,
.buf = i2c->i2c_read_buffer, .len = 2},
}; };
msg[0].buf[0] = reg >> 8;
msg[0].buf[1] = reg & 0xff;
if (i2c_transfer(i2c->adap, msg, 2) != 2) if (i2c_transfer(i2c->adap, msg, 2) != 2)
dprintk("i2c read error on %d", reg); dprintk("i2c read error on %d", reg);
return (rb[0] << 8) | rb[1]; return (msg[1].buf[0] << 8) | msg[1].buf[1];
} }
static u16 dib8000_read_word(struct dib8000_state *state, u16 reg) static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
{ {
return dib8000_i2c_read16(&state->i2c, reg); state->i2c_write_buffer[0] = reg >> 8;
state->i2c_write_buffer[1] = reg & 0xff;
memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
state->msg[0].addr = state->i2c.addr >> 1;
state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 2;
state->msg[1].addr = state->i2c.addr >> 1;
state->msg[1].flags = I2C_M_RD;
state->msg[1].buf = state->i2c_read_buffer;
state->msg[1].len = 2;
if (i2c_transfer(state->i2c.adap, state->msg, 2) != 2)
dprintk("i2c read error on %d", reg);
return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
} }
static u32 dib8000_read32(struct dib8000_state *state, u16 reg) 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,19 +135,34 @@ static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val) static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
{ {
u8 b[4] = { struct i2c_msg msg = {.addr = i2c->addr >> 1, .flags = 0,
(reg >> 8) & 0xff, reg & 0xff, .buf = i2c->i2c_write_buffer, .len = 4};
(val >> 8) & 0xff, val & 0xff, int ret = 0;
};
struct i2c_msg msg = { msg.buf[0] = (reg >> 8) & 0xff;
.addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4 msg.buf[1] = reg & 0xff;
}; msg.buf[2] = (val >> 8) & 0xff;
return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0; msg.buf[3] = val & 0xff;
ret = i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
return ret;
} }
static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val) static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
{ {
return dib8000_i2c_write16(&state->i2c, reg, val); state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
state->i2c_write_buffer[1] = reg & 0xff;
state->i2c_write_buffer[2] = (val >> 8) & 0xff;
state->i2c_write_buffer[3] = val & 0xff;
memset(&state->msg[0], 0, sizeof(struct i2c_msg));
state->msg[0].addr = state->i2c.addr >> 1;
state->msg[0].flags = 0;
state->msg[0].buf = state->i2c_write_buffer;
state->msg[0].len = 4;
return i2c_transfer(state->i2c.adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
} }
static const s16 coeff_2k_sb_1seg_dqpsk[8] = { static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
...@@ -980,18 +1021,7 @@ static void dib8000_update_timf(struct dib8000_state *state) ...@@ -980,18 +1021,7 @@ static void dib8000_update_timf(struct dib8000_state *state)
dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default); dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
} }
static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching) static const u16 adc_target_16dB[11] = {
{
u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
u8 guard, crate, constellation, timeI;
u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
const s16 *ncoeff = NULL, *ana_fe;
u16 tmcc_pow = 0;
u16 coff_pow = 0x2800;
u16 init_prbs = 0xfff;
u16 ana_gain = 0;
u16 adc_target_16dB[11] = {
(1 << 13) - 825 - 117, (1 << 13) - 825 - 117,
(1 << 13) - 837 - 117, (1 << 13) - 837 - 117,
(1 << 13) - 811 - 117, (1 << 13) - 811 - 117,
...@@ -1003,7 +1033,19 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear ...@@ -1003,7 +1033,19 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
(1 << 13) - 575 - 117, (1 << 13) - 575 - 117,
(1 << 13) - 531 - 117, (1 << 13) - 531 - 117,
(1 << 13) - 501 - 117 (1 << 13) - 501 - 117
}; };
static const u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
{
u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
u8 guard, crate, constellation, timeI;
u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
const s16 *ncoeff = NULL, *ana_fe;
u16 tmcc_pow = 0;
u16 coff_pow = 0x2800;
u16 init_prbs = 0xfff;
u16 ana_gain = 0;
if (state->ber_monitored_layer != LAYER_ALL) if (state->ber_monitored_layer != LAYER_ALL)
dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer); 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,10 +2421,22 @@ EXPORT_SYMBOL(dib8000_get_slave_frontend);
int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
{ {
int k = 0; int k = 0, ret = 0;
u8 new_addr = 0; u8 new_addr = 0;
struct i2c_device client = {.adap = host }; struct i2c_device client = {.adap = host };
client.i2c_write_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
if (!client.i2c_write_buffer) {
dprintk("%s: not enough memory", __func__);
return -ENOMEM;
}
client.i2c_read_buffer = kzalloc(4 * sizeof(u8), GFP_KERNEL);
if (!client.i2c_read_buffer) {
dprintk("%s: not enough memory", __func__);
ret = -ENOMEM;
goto error_memory;
}
for (k = no_of_demods - 1; k >= 0; k--) { for (k = no_of_demods - 1; k >= 0; k--) {
/* designated i2c address */ /* designated i2c address */
new_addr = first_addr + (k << 1); 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,7 +2448,8 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau
client.addr = default_addr; client.addr = default_addr;
if (dib8000_identify(&client) == 0) { if (dib8000_identify(&client) == 0) {
dprintk("#%d: not identified", k); dprintk("#%d: not identified", k);
return -EINVAL; ret = -EINVAL;
goto error;
} }
} }
...@@ -2420,7 +2475,12 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau ...@@ -2420,7 +2475,12 @@ int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 defau
dib8000_i2c_write16(&client, 1286, 0); dib8000_i2c_write16(&client, 1286, 0);
} }
return 0; error:
kfree(client.i2c_read_buffer);
error_memory:
kfree(client.i2c_write_buffer);
return ret;
} }
EXPORT_SYMBOL(dib8000_i2c_enumeration); EXPORT_SYMBOL(dib8000_i2c_enumeration);
...@@ -2519,6 +2579,8 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s ...@@ -2519,6 +2579,8 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s
memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
state->i2c.adap = i2c_adap; state->i2c.adap = i2c_adap;
state->i2c.addr = i2c_addr; state->i2c.addr = i2c_addr;
state->i2c.i2c_write_buffer = state->i2c_write_buffer;
state->i2c.i2c_read_buffer = state->i2c_read_buffer;
state->gpio_val = cfg->gpio_val; state->gpio_val = cfg->gpio_val;
state->gpio_dir = cfg->gpio_dir; state->gpio_dir = cfg->gpio_dir;
......
This diff is collapsed.
...@@ -10,30 +10,39 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); ...@@ -10,30 +10,39 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val) static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
{ {
u8 b[4] = { mst->i2c_write_buffer[0] = (reg >> 8) & 0xff;
(reg >> 8) & 0xff, reg & 0xff, mst->i2c_write_buffer[1] = reg & 0xff;
(val >> 8) & 0xff, val & 0xff, mst->i2c_write_buffer[2] = (val >> 8) & 0xff;
}; mst->i2c_write_buffer[3] = val & 0xff;
struct i2c_msg msg = {
.addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4 memset(mst->msg, 0, sizeof(struct i2c_msg));
}; mst->msg[0].addr = mst->i2c_addr;
mst->msg[0].flags = 0;
return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; mst->msg[0].buf = mst->i2c_write_buffer;
mst->msg[0].len = 4;
return i2c_transfer(mst->i2c_adap, mst->msg, 1) != 1 ? -EREMOTEIO : 0;
} }
static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg) static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
{ {
u8 wb[2] = { reg >> 8, reg & 0xff }; mst->i2c_write_buffer[0] = reg >> 8;
u8 rb[2]; mst->i2c_write_buffer[1] = reg & 0xff;
struct i2c_msg msg[2] = {
{.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2}, memset(mst->msg, 0, 2 * sizeof(struct i2c_msg));
{.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2}, mst->msg[0].addr = mst->i2c_addr;
}; mst->msg[0].flags = 0;
mst->msg[0].buf = mst->i2c_write_buffer;
if (i2c_transfer(mst->i2c_adap, msg, 2) != 2) mst->msg[0].len = 2;
mst->msg[1].addr = mst->i2c_addr;
mst->msg[1].flags = I2C_M_RD;
mst->msg[1].buf = mst->i2c_read_buffer;
mst->msg[1].len = 2;
if (i2c_transfer(mst->i2c_adap, mst->msg, 2) != 2)
dprintk("i2c read error on %d", reg); dprintk("i2c read error on %d", reg);
return (rb[0] << 8) | rb[1]; return (mst->i2c_read_buffer[0] << 8) | mst->i2c_read_buffer[1];
} }
static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst) 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,26 +257,32 @@ static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg msg[], int num) struct i2c_msg msg[], int num)
{ {
struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
struct i2c_msg m[2 + num];
u8 tx_open[4], tx_close[4];
memset(m, 0, sizeof(struct i2c_msg) * (2 + num)); if (num > 32) {
dprintk("%s: too much I2C message to be transmitted (%i).\
Maximum is 32", __func__, num);
return -ENOMEM;
}
memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7); dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); /* open the gate */
m[0].addr = mst->i2c_addr; dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
m[0].buf = tx_open; mst->msg[0].addr = mst->i2c_addr;
m[0].len = 4; mst->msg[0].buf = &mst->i2c_write_buffer[0];
mst->msg[0].len = 4;
memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); /* close the gate */
m[num + 1].addr = mst->i2c_addr; dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
m[num + 1].buf = tx_close; mst->msg[num + 1].addr = mst->i2c_addr;
m[num + 1].len = 4; mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
mst->msg[num + 1].len = 4;
return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO; return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
} }
static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = { 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,26 +294,32 @@ static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg msg[], int num) struct i2c_msg msg[], int num)
{ {
struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
struct i2c_msg m[2 + num];
u8 tx_open[4], tx_close[4];
memset(m, 0, sizeof(struct i2c_msg) * (2 + num)); if (num > 32) {
dprintk("%s: too much I2C message to be transmitted (%i).\
Maximum is 32", __func__, num);
return -ENOMEM;
}
memset(mst->msg, 0, sizeof(struct i2c_msg) * (2 + num));
dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); /* open the gate */
m[0].addr = mst->i2c_addr; dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[0], msg[0].addr, 1);
m[0].buf = tx_open; mst->msg[0].addr = mst->i2c_addr;
m[0].len = 4; mst->msg[0].buf = &mst->i2c_write_buffer[0];
mst->msg[0].len = 4;
memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); memcpy(&mst->msg[1], msg, sizeof(struct i2c_msg) * num);
dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); /* close the gate */
m[num + 1].addr = mst->i2c_addr; dibx000_i2c_gate_ctrl(mst, &mst->i2c_write_buffer[4], 0, 0);
m[num + 1].buf = tx_close; mst->msg[num + 1].addr = mst->i2c_addr;
m[num + 1].len = 4; mst->msg[num + 1].buf = &mst->i2c_write_buffer[4];
mst->msg[num + 1].len = 4;
return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO; return i2c_transfer(mst->i2c_adap, mst->msg, 2 + num) == 2 + num ? num : -EIO;
} }
static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
......
...@@ -28,6 +28,11 @@ struct dibx000_i2c_master { ...@@ -28,6 +28,11 @@ struct dibx000_i2c_master {
u8 i2c_addr; u8 i2c_addr;
u16 base_reg; u16 base_reg;
/* for the I2C transfer */
struct i2c_msg msg[34];
u8 i2c_write_buffer[8];
u8 i2c_read_buffer[2];
}; };
extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment