Hi Markus,
I have a question about the GPIO registers. In em28xx-i2c.c there is the
em28xx_gpio_control() function. Here the sometimes the lower 3 and sometimes
the lower 4 bits of the 16bit gpio_value is used in the "left bit shift"
operation. The shift is applied to an 8 bit value, which means. In case when
only the lower 3 bits are used the result will be:
gpio_value & 7 | (u8)(1 << (gpio_value & 7))
----------------+-----------------------------
0 | 1
1 | 2
2 | 4
3 | 8
4 | 16
5 | 32
6 | 64
7 | 128
However, when the lower 4 bits are used for shifting an 8bit value, then the
result maybe sometimes something different what expected:
gpio_value & 0xf | (u8)(1 << (gpio_value & 0xf))
-----------------+-------------------------------
0 | 1
1 | 2
2 | 4
3 | 8
4 | 16
5 | 32
6 | 64
7 | 128
8 | 0
9 | 0
10 | 0
11 | 0
12 | 0
13 | 0
14 | 0
15 | 0
Is this how it should work?
> int em28xx_gpio_control(void *priv, unsigned int command, void *ptr)
> {
> struct em28xx *dev = (struct em28xx *)priv;
> unsigned int len;
> u16 gpio_value;
> u8 gpio;
> int *arg = ptr;
> u16 gpio_reg;
> int ret = 0;
>
> [... fetch gpio_value ...]
>
> /* check if gpio register enabled */
> if (gpio_value & 0x80) {
> if (((gpio_value >> 6)&1) == 0) {
> if (arg == NULL) {
> printk(KERN_INFO"no argument given %02x\n",
> gpio_value);
> return -EINVAL;
> }
> /* on/off command */
> switch (dev->em_type) {
> case EM2888:
> case EM2889:
> case EM2875:
> gpio_reg = 0x80;
> break;
> case EM2883:
> default:
> gpio_reg = gpio_value&0x10 ? 0x04 : 0x08;
> break;
> }
> gpio = dev->em28xx_read_reg(dev, gpio_reg);
> gpio &= ~((u8)(1 << (gpio_value&0x7)));
Lower 3 bits is used here for shifting.
>
> if (*arg == EM28XX_REG_ON)
> gpio |= ((gpio_value >> 5)&1) <<
> (gpio_value&7);
Lower 3 bits again.
> else
> gpio |= (((gpio_value >> 5)&1)^1) <<
> (gpio_value&7);
Lower 3 bits of gpio_value for shifting.
>
> dev->em28xx_write_regs(dev, gpio_reg, &gpio, 1);
> dprintk1(2, "(1) writing to %02x -> %02x\n", gpio_reg,
> gpio);
> } else {
> switch (dev->em_type) {
> case EM2889:
> case EM2888:
> case EM2875:
> gpio_reg = 0x80;
> break;
> case EM2883:
> default:
> gpio_reg = gpio_value&0x10 ? 0x04 : 0x08;
> break;
> }
> gpio = dev->em28xx_read_reg(dev, gpio_reg);
> gpio &= ~((u8)(1 << (gpio_value&0xf)));
Here the lower 4 bits are used for shifting.
>
> gpio |= ((gpio_value >> 5)&1) << (gpio_value&7);
Lower 3 bits.
> dev->em28xx_write_regs(dev, gpio_reg, &gpio, 1);
> dprintk1(2, "(2) writing to %02x -> %02x\n", gpio_reg,
> gpio);
> gpio &= ~((u8)(1 << (gpio_value&0xf)));
Lower 4 bits.
> gpio |= (((gpio_value >> 5)&1)^1) << (gpio_value&7);
Lower 3 bits.
> mdelay(100);
> dev->em28xx_write_regs(dev, gpio_reg, &gpio, 1);
> mdelay(100);
> dprintk1(2, "(3) writing to %02x -> %02x\n", gpio_reg,
> gpio);
> }
> } else {
> printk("register disabled\n");
> }
>
> return 0;
> }
Regards,
Márton Németh
_______________________________________________
Em28xx mailing list
[email protected]
http://mcentral.de/mailman/listinfo/em28xx