V4L/DVB (10567): bttv: shrink muxsel data in card database

Over half of the card database was used to store muxsel data.  64 bytes
were used to store one 32 bit word for each of up to 16 inputs.

The Bt8x8 only has two bits to control its mux, so muxsel data for 16
inputs will fit into a single 32 bit word.  There were a couple cards that
had special muxsel data that didn't fit in two bits, but I cleaned them up
in earlier patches.

Unfortunately, C doesn't allow us to have an array of bit fields.  This
makes initializing the structure more of a pain.  But with some cpp magic,
we can do it by changing:
	.muxsel = { 2, 3, 0, 1 },
	.muxsel = { 2, 2, 2, 2, 3, 3, 3, 3, 1, 1 },
Into:
	.muxsel = MUXSEL(2, 3, 0, 1),
	.muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1),

That's not so bad.  MUXSEL is a fancy macro that packs the arguments (of
which there can be one to sixteen!) into a single word two bits at a time.
It's a compile time constant (a variadic function wouldn't be) so we can
use it to initialize the structure.  It's important the the arguments to
the macro only be plain decimal integers.  Stuff like "0x01", "(2)", or
"MUX3" won't work properly.

I also created an accessor function, bttv_muxsel(btv, input), that gets the
mux bits for the selected input.  It makes it cleaner to change the way the
muxsel data is stored.

This patch doesn't change the code size and decreases the datasegment by
9440 bytes.

Signed-off-by: Trent Piepho <xyzzy@speakeasy.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
Trent Piepho 2009-01-28 21:32:59 -03:00 коммит произвёл Mauro Carvalho Chehab
Родитель 430390e67b
Коммит 6f98700a5b
4 изменённых файлов: 195 добавлений и 159 удалений

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1142,7 +1142,7 @@ video_mux(struct bttv *btv, unsigned int input)
btand(~BT848_CONTROL_COMP, BT848_E_CONTROL); btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
btand(~BT848_CONTROL_COMP, BT848_O_CONTROL); btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
} }
mux = bttv_tvcards[btv->c.type].muxsel[input] & 3; mux = bttv_muxsel(btv, input);
btaor(mux<<5, ~(3<<5), BT848_IFORM); btaor(mux<<5, ~(3<<5), BT848_IFORM);
dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n", dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n",
btv->c.nr,input,mux); btv->c.nr,input,mux);

Просмотреть файл

@ -206,15 +206,16 @@ struct bttv_core {
struct bttv; struct bttv;
struct tvcard { struct tvcard {
char *name; char *name;
void (*volume_gpio)(struct bttv *btv, __u16 volume); void (*volume_gpio)(struct bttv *btv, __u16 volume);
void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set); void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
void (*muxsel_hook)(struct bttv *btv, unsigned int input); void (*muxsel_hook)(struct bttv *btv, unsigned int input);
/* MUX bits for each input, two bits per input starting with the LSB */
u32 muxsel; /* Use MUXSEL() to set */
u32 gpiomask; u32 gpiomask;
u32 muxsel[16];
u32 gpiomux[4]; /* Tuner, Radio, external, internal */ u32 gpiomux[4]; /* Tuner, Radio, external, internal */
u32 gpiomute; /* GPIO mute setting */ u32 gpiomute; /* GPIO mute setting */
u32 gpiomask2; /* GPIO MUX mask */ u32 gpiomask2; /* GPIO MUX mask */
@ -246,6 +247,31 @@ struct tvcard {
extern struct tvcard bttv_tvcards[]; extern struct tvcard bttv_tvcards[];
/*
* This bit of cpp voodoo is used to create a macro with a variable number of
* arguments (1 to 16). It will pack each argument into a word two bits at a
* time. It can't be a function because it needs to be compile time constant to
* initialize structures. Since each argument must fit in two bits, it's ok
* that they are changed to octal. One should not use hex number, macros, or
* anything else with this macro. Just use plain integers from 0 to 3.
*/
#define _MUXSELf(a) 0##a << 30
#define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b)
#define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b)
#define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b)
#define _MUXSELb(a, b...) 0##a << 22 | _MUXSELc(b)
#define _MUXSELa(a, b...) 0##a << 20 | _MUXSELb(b)
#define _MUXSEL9(a, b...) 0##a << 18 | _MUXSELa(b)
#define _MUXSEL8(a, b...) 0##a << 16 | _MUXSEL9(b)
#define _MUXSEL7(a, b...) 0##a << 14 | _MUXSEL8(b)
#define _MUXSEL6(a, b...) 0##a << 12 | _MUXSEL7(b)
#define _MUXSEL5(a, b...) 0##a << 10 | _MUXSEL6(b)
#define _MUXSEL4(a, b...) 0##a << 8 | _MUXSEL5(b)
#define _MUXSEL3(a, b...) 0##a << 6 | _MUXSEL4(b)
#define _MUXSEL2(a, b...) 0##a << 4 | _MUXSEL3(b)
#define _MUXSEL1(a, b...) 0##a << 2 | _MUXSEL2(b)
#define MUXSEL(a, b...) (a | _MUXSEL1(b))
/* identification / initialization of the card */ /* identification / initialization of the card */
extern void bttv_idcard(struct bttv *btv); extern void bttv_idcard(struct bttv *btv);
extern void bttv_init_card1(struct bttv *btv); extern void bttv_init_card1(struct bttv *btv);

Просмотреть файл

@ -464,6 +464,12 @@ struct bttv {
extern unsigned int bttv_num; extern unsigned int bttv_num;
extern struct bttv bttvs[BTTV_MAX]; extern struct bttv bttvs[BTTV_MAX];
static inline unsigned int bttv_muxsel(const struct bttv *btv,
unsigned int input)
{
return (bttv_tvcards[btv->c.type].muxsel >> (input * 2)) & 3;
}
#endif #endif
#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr)) #define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr))