int m5602_read_sensor(struct sd *sd, const u8 address, u8 *i2c_data, const u8 len) { int err, i; if (!len || len > sd->sensor->i2c_regW) return -EINVAL; do { err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, i2c_data); } while ((*i2c_data & I2C_BUSY) && !err); if (err < 0) goto out; err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, sd->sensor->i2c_slave_id); if (err < 0) goto out; err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); if (err < 0) goto out; if (sd->sensor->i2c_regW == 1) { err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, len); if (err < 0) goto out; err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); if (err < 0) goto out; } else { err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); if (err < 0) goto out; } for (i = 0; (i < len) && !err; i++) { err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); PDEBUG(D_CONF, "Reading sensor register " "0x%x containing 0x%x ", address, *i2c_data); } out: return err; }
static int m5602_wait_for_i2c(struct sd *sd) { int err; u8 data; do { err = m5602_read_bridge(sd, M5602_XB_I2C_STATUS, &data); } while ((data & I2C_BUSY) && !err); return err; }
static void m5602_dump_bridge(struct sd *sd) { int i; for (i = 0; i < 0x80; i++) { unsigned char val = 0; m5602_read_bridge(sd, i, &val); pr_info("ALi m5602 address 0x%x contains 0x%x\n", i, val); } pr_info("Warning: The ALi m5602 webcam probably won't work until it's power cycled\n"); }
int m5602_read_sensor(struct sd *sd, const u8 address, u8 *i2c_data, const u8 len) { int err, i; struct gspca_dev *gspca_dev = (struct gspca_dev *) sd; if (!len || len > sd->sensor->i2c_regW) return -EINVAL; err = m5602_wait_for_i2c(sd); if (err < 0) return err; err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, sd->sensor->i2c_slave_id); if (err < 0) return err; err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); if (err < 0) return err; /* Sensors with registers that are of only one byte width are differently read */ /* FIXME: This works with the ov9650, but has issues with the po1030 */ if (sd->sensor->i2c_regW == 1) { err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1); if (err < 0) return err; err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); } else { err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); } for (i = 0; (i < len) && !err; i++) { err = m5602_wait_for_i2c(sd); if (err < 0) return err; err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); gspca_dbg(gspca_dev, D_CONF, "Reading sensor register 0x%x containing 0x%x\n", address, *i2c_data); } return err; }
int m5602_read_sensor(struct sd *sd, const u8 address, u8 *i2c_data, const u8 len) { int err, i; if (!len || len > sd->sensor->i2c_regW) return -EINVAL; err = m5602_wait_for_i2c(sd); if (err < 0) return err; err = m5602_write_bridge(sd, M5602_XB_I2C_DEV_ADDR, sd->sensor->i2c_slave_id); if (err < 0) return err; err = m5602_write_bridge(sd, M5602_XB_I2C_REG_ADDR, address); if (err < 0) return err; /* Sensors with registers that are of only one byte width are differently read */ if (sd->sensor->i2c_regW == 1) { err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 1); if (err < 0) return err; err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x08); } else { err = m5602_write_bridge(sd, M5602_XB_I2C_CTRL, 0x18 + len); } for (i = 0; (i < len) && !err; i++) { err = m5602_wait_for_i2c(sd); if (err < 0) return err; err = m5602_read_bridge(sd, M5602_XB_I2C_DATA, &(i2c_data[i])); PDEBUG(D_CONF, "Reading sensor register " "0x%x containing 0x%x ", address, *i2c_data); } return err; }
static int s5k83a_set_led_indication(struct sd *sd, u8 val) { int err = 0; u8 data[1]; err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, data); if (err < 0) return err; if (val) data[0] = data[0] | S5K83A_GPIO_LED_MASK; else data[0] = data[0] & ~S5K83A_GPIO_LED_MASK; err = m5602_write_bridge(sd, M5602_XB_GPIO_DAT, data[0]); return err; }
/* Get camera rotation on Acer notebooks */ static int s5k83a_get_rotation(struct sd *sd, u8 *reg_data) { int err = m5602_read_bridge(sd, M5602_XB_GPIO_DAT, reg_data); *reg_data = (*reg_data & S5K83A_GPIO_ROTATION_MASK) ? 0 : 1; return err; }