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

Reply via email to