static ssize_t lp855x_ctrl_register(struct file *file, const char __user *userbuf, size_t count, loff_t *ppos) { char mode, buf[20]; char *pos, *pos2; u8 i, arg1, arg2, val; struct lp855x *lp = file->private_data; int rc; size_t offs; if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) return -EFAULT; mode = buf[count - 2]; switch (mode) { case 'r': if (!lp855x_parse_register_cmd(buf, count, &arg1)) return -EINVAL; rc = lp855x_read_byte(lp, arg1, &val); dev_info(lp->dev, "Read [0x%.2x] = 0x%.2x\n", arg1, val); break; case 'w': pos = lp855x_parse_register_cmd(buf, count, &arg1); if (!pos) return -EINVAL; offs = pos - buf; pos2 = lp855x_parse_register_cmd(pos + 1, count - offs, &arg2); if (!pos2) return -EINVAL; rc = lp855x_write_byte(lp, arg1, arg2); dev_info(lp->dev, "Written [0x%.2x] = 0x%.2x\n", arg1, arg2); break; case 'd': pos = lp855x_parse_register_cmd(buf, count, &arg1); if (!pos) return -EINVAL; offs = pos - buf; pos2 = lp855x_parse_register_cmd(pos + 1, count - offs, &arg2); if (!pos2) return -EINVAL; for (rc = 0, i = arg1; i <= arg2 && !rc; i++) { rc = lp855x_read_byte(lp, i, &val); dev_info(lp->dev, "Read [0x%.2x] = 0x%.2x\n", i, val); } break; default: rc = -EINVAL; break; } return rc ? rc : count; }
static void lp855x_init_device(struct lp855x *lp) { u8 val, addr; int i, ret; struct lp855x_platform_data *pd = lp->pdata; val = pd->device_control; ret = lp855x_write_byte(lp, DEVICE_CTRL, val); if (pd->load_new_rom_data && pd->size_program) { for (i = 0; i < pd->size_program; i++) { addr = pd->rom_data[i].addr; val = pd->rom_data[i].val; if (!lp855x_is_valid_rom_area(lp, addr)) continue; if (addr == CFG98_CTRL) { u8 cfg98; lp855x_read_byte(lp, CFG98_CTRL, &cfg98); cfg98 &= ~IBOOST_LIM_2X_MASK; val = cfg98 | (val & IBOOST_LIM_2X_MASK); } ret |= lp855x_write_byte(lp, addr, val); } } ret |= lp855x_write_byte(lp, CFG3_CTRL, pd->cfg3); if (ret) dev_err(lp->dev, "i2c write err\n"); }
static int lp855x_resume_init(struct lp855x *lp) { u8 val, addr; int i, ret = 0; if (lp->cfg->pre_init_device) { ret = lp->cfg->pre_init_device(lp); if (ret) { dev_err(lp->dev, "pre init device err: %d\n", ret); goto exit; } } if (lp->pdata->size_program > 0) { for (i = 0; i < lp->pdata->size_program; i++) { addr = lp->pdata->rom_data[i].addr; val = lp->pdata->rom_data[i].val; if (!lp855x_is_valid_rom_area(lp, addr)) continue; if (addr == CFG98_CTRL) { u8 cfg98; lp855x_read_byte(lp, CFG98_CTRL, &cfg98); cfg98 &= ~IBOOST_LIM_2X_MASK; val = cfg98 | (val & IBOOST_LIM_2X_MASK); } ret = lp855x_write_byte(lp, addr, val); if (ret) { dev_err(lp->dev, "set register err: %d\n", ret); goto exit; } } } ret = lp855x_write_byte(lp, lp->cfg->reg_slope, lp->pdata->slope_reg); if (ret) { dev_err(lp->dev, "i2c write err\n"); goto exit; } if (lp->cfg->post_init_device) { ret = lp->cfg->post_init_device(lp); if (ret) { dev_err(lp->dev, "post init device err: %d\n", ret); goto exit; } } exit: return ret; }
static int lp855x_init_registers(struct lp855x *lp) { u8 val, addr, mask; int i, ret; struct lp855x_platform_data *pd = lp->pdata; val = pd->initial_brightness; ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val); if (ret) return ret; val = pd->device_control; ret = lp855x_write_byte(lp, DEVICE_CTRL, val); if (ret) return ret; if (pd->load_new_rom_data && pd->size_program) { for (i = 0; i < pd->size_program; i++) { addr = pd->rom_data[i].addr; val = pd->rom_data[i].val; mask = pd->rom_data[i].mask; if (!lp855x_is_valid_rom_area(lp, addr)) continue; if (mask) { u8 reg_val; ret = lp855x_read_byte(lp, addr, ®_val); if (ret) return ret; val = (val & ~mask) | (reg_val & mask); } ret = lp855x_write_byte(lp, addr, val); if (ret) return ret; } } return ret; }
static int lp855x_bl_get_brightness(struct backlight_device *bl) { struct lp855x *lp = bl_get_data(bl); enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode; if (mode == PWM_BASED) { struct lp855x_pwm_data *pd = &lp->pdata->pwm_data; int max_br = bl->props.max_brightness; if (pd->pwm_get_intensity) bl->props.brightness = pd->pwm_get_intensity(max_br); } else if (mode == REGISTER_BASED) { u8 val = 0; lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val); bl->props.brightness = val; } return (bl->props.brightness); }
static int lp855x_check_need_config(struct lp855x *lp, bool *need_config_flg) { int ret = 0; u8 val; if (!bl_on_in_boot) { *need_config_flg = true; goto exit; } ret = lp855x_read_byte(lp, lp->cfg->reg_devicectrl, &val); if (ret) { dev_err(lp->dev, "Read ctrl register[0x%.04x] err: %d\n", lp->cfg->reg_devicectrl, ret); goto exit; } if (val & lp->cfg->reg_devicectrl_mask) *need_config_flg = false; else *need_config_flg = true; exit: return ret; }
/* * Device specific configuration flow * * a) pre_init_device(optional) * b) update the brightness register * c) update ROM area(optional) * d) post_init_device(optional) * */ static int lp855x_configure(struct lp855x *lp) { u8 val, addr; bool need_config; int i, ret, brightness; struct lp855x_platform_data *pd = lp->pdata; switch (lp->chipid->driver_data) { case LP8550 ... LP8556: lp->cfg = &lp855x_dev_cfg; break; case LP8557: lp->cfg = &lp8557_dev_cfg; break; default: ret = -EINVAL; dev_err(lp->dev, "device support err: %d\n", ret); goto exit; } ret = lp855x_check_need_config(lp, &need_config); if (ret || !need_config) goto exit; if (lp->cfg->pre_init_device) { ret = lp->cfg->pre_init_device(lp); if (ret) { dev_err(lp->dev, "pre init device err: %d\n", ret); goto exit; } } brightness = pd->initial_brightness; ret = lp855x_write_brightness(lp, lp->cfg->is_8bit_brightness, brightness); if (ret) { dev_err(lp->dev, "set initial brightness err: %d\n", ret); goto exit; } if (pd->size_program > 0) { for (i = 0; i < pd->size_program; i++) { addr = pd->rom_data[i].addr; val = pd->rom_data[i].val; if (!lp855x_is_valid_rom_area(lp, addr)) continue; if (addr == CFG98_CTRL) { u8 cfg98; lp855x_read_byte(lp, CFG98_CTRL, &cfg98); cfg98 &= ~IBOOST_LIM_2X_MASK; val = cfg98 | (val & IBOOST_LIM_2X_MASK); } ret = lp855x_write_byte(lp, addr, val); if (ret) { dev_err(lp->dev, "set register err: %d\n", ret); goto exit; } } } ret = lp855x_write_byte(lp, lp->cfg->reg_slope, pd->slope_reg); if (ret) { dev_err(lp->dev, "i2c write err\n"); goto exit; } if (lp->cfg->post_init_device) { ret = lp->cfg->post_init_device(lp); if (ret) { dev_err(lp->dev, "post init device err: %d\n", ret); goto exit; } } exit: return ret; }