static int stk1160_i2c_read_reg(struct stk1160 *dev, u8 addr, u8 reg, u8 *value) { int rc; /* Set serial device address */ rc = stk1160_write_reg(dev, STK1160_SICTL_SDA, addr); if (rc < 0) return rc; /* Set i2c device register sub-address */ rc = stk1160_write_reg(dev, STK1160_SBUSR_RA, reg); if (rc < 0) return rc; /* Start read now */ rc = stk1160_write_reg(dev, STK1160_SICTL, 0x20); if (rc < 0) return rc; rc = stk1160_i2c_busy_wait(dev, 0x01); if (rc < 0) return rc; stk1160_read_reg(dev, STK1160_SBUSR_RD, value); if (rc < 0) return rc; return 0; }
static int vidioc_g_register(struct file *file, void *priv, struct v4l2_dbg_register *reg) { struct stk1160 *dev = video_drvdata(file); int rc; u8 val; switch (reg->match.type) { case V4L2_CHIP_MATCH_AC97: /* TODO: Support me please :-( */ return -EINVAL; case V4L2_CHIP_MATCH_I2C_DRIVER: v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg); return 0; case V4L2_CHIP_MATCH_I2C_ADDR: /* TODO: is this correct? */ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg); return 0; default: if (!v4l2_chip_match_host(®->match)) return -EINVAL; } /* Match host */ rc = stk1160_read_reg(dev, reg->reg, &val); reg->val = val; reg->size = 1; return rc; }
static int vidioc_g_register(struct file *file, void *priv, struct v4l2_dbg_register *reg) { struct stk1160 *dev = video_drvdata(file); int rc; u8 val; /* Match host */ rc = stk1160_read_reg(dev, reg->reg, &val); reg->val = val; reg->size = 1; return rc; }
static int stk1160_i2c_busy_wait(struct stk1160 *dev, u8 wait_bit_mask) { unsigned long end; u8 flag; /* Wait until read/write finish bit is set */ end = jiffies + msecs_to_jiffies(STK1160_I2C_TIMEOUT); while (time_is_after_jiffies(end)) { stk1160_read_reg(dev, STK1160_SICTL+1, &flag); /* read/write done? */ if (flag & wait_bit_mask) goto done; usleep_range(10 * USEC_PER_MSEC, 20 * USEC_PER_MSEC); } return -ETIMEDOUT; done: return 0; }