Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] cx24116: add config option to split firmware download

It is very rare I2C adapter hardware which can provide 32kB I2C write
as one write. Add .i2c_wr_max option to set desired max packet size.
Split transaction to smaller pieces according to that option.

Signed-off-by: Antti Palosaari <crope@iki.fi>
Cc: Steven Toth <stoth@hauppauge.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>

authored by

Antti Palosaari and committed by
Mauro Carvalho Chehab
107d7b18 f3b1af19

+17 -3
+14 -3
drivers/media/dvb/frontends/cx24116.c
··· 566 566 { 567 567 struct cx24116_state *state = fe->demodulator_priv; 568 568 struct cx24116_cmd cmd; 569 - int i, ret; 569 + int i, ret, len, remaining; 570 570 unsigned char vers[4]; 571 571 572 572 dprintk("%s\n", __func__); ··· 603 603 cx24116_writereg(state, 0xF5, 0x00); 604 604 cx24116_writereg(state, 0xF6, 0x00); 605 605 606 - /* write the entire firmware as one transaction */ 607 - cx24116_writeregN(state, 0xF7, fw->data, fw->size); 606 + /* Split firmware to the max I2C write len and write. 607 + * This overflows 16 bit intentionally in order to get max write 608 + * len when i2c_wr_max is set to 0. */ 609 + for (remaining = fw->size; remaining > 0; 610 + remaining -= (u16) (state->config->i2c_wr_max - 1)) { 611 + 612 + len = remaining; 613 + if (len > (u16) (state->config->i2c_wr_max - 1)) 614 + len = (u16) (state->config->i2c_wr_max - 1); 615 + 616 + cx24116_writeregN(state, 0xF7, &fw->data[fw->size - remaining], 617 + len); 618 + } 608 619 609 620 cx24116_writereg(state, 0xF4, 0x10); 610 621 cx24116_writereg(state, 0xF0, 0x00);
+3
drivers/media/dvb/frontends/cx24116.h
··· 35 35 36 36 /* Need to set MPEG parameters */ 37 37 u8 mpg_clk_pos_pol:0x02; 38 + 39 + /* max bytes I2C provider can write at once */ 40 + u16 i2c_wr_max; 38 41 }; 39 42 40 43 #if defined(CONFIG_DVB_CX24116) || \