static bool is_volatile_palmas_func_reg(struct device *dev, unsigned int reg) { if ((reg >= PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, PALMAS_SMPS12_CTRL)) && (reg <= PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, PALMAS_SMPS9_VOLTAGE))) { struct palmas *palmas = dev_get_drvdata(dev); int volatile_reg = test_bit( PALMAS_REG_TO_FN_ADDR(PALMAS_SMPS_BASE, reg), palmas->volatile_smps_registers); if (!volatile_reg) return false; } return true; }
int palmas_gpio_read(struct palmas *palmas, unsigned int reg, unsigned int *dest) { unsigned int addr; addr = PALMAS_BASE_TO_REG(PALMAS_GPIO_BASE, reg); return regmap_read(palmas->regmap[GPIO_SLAVE], addr, dest); }
static int palmas_reg_volatile_set(struct device *dev, unsigned int reg, bool is_volatile) { if ((reg >= PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, PALMAS_SMPS12_CTRL)) && (reg <= PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, PALMAS_SMPS9_VOLTAGE))) { struct palmas *palmas = dev_get_drvdata(dev); unsigned int bit = PALMAS_REG_TO_FN_ADDR(PALMAS_SMPS_BASE, reg); if (is_volatile) set_bit(bit, palmas->volatile_smps_registers); else clear_bit(bit, palmas->volatile_smps_registers); return 0; } return -EINVAL; }
int palmas_gpio_write(struct palmas *palmas, unsigned int reg, unsigned int value) { unsigned int addr; addr = PALMAS_BASE_TO_REG(PALMAS_GPIO_BASE, reg); return regmap_write(palmas->regmap[GPIO_SLAVE], addr, value); }
static int palmas_ldo_write(struct palmas *palmas, unsigned int reg, unsigned int value) { unsigned int addr; addr = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, reg); return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value); }
static int palmas_ldo_read(struct palmas *palmas, unsigned int reg, unsigned int *dest) { unsigned int addr; addr = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, reg); return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest); }
static int palmas_gpio_read(struct palmas *palmas, unsigned int reg, unsigned int *dest) { unsigned int addr; int slave; slave = PALMAS_BASE_TO_SLAVE(PALMAS_GPIO_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_GPIO_BASE, reg); return regmap_read(palmas->regmap[slave], addr, dest); }
static int palmas_gpio_write(struct palmas *palmas, unsigned int reg, unsigned int data) { unsigned int addr; int slave; slave = PALMAS_BASE_TO_SLAVE(PALMAS_GPIO_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_GPIO_BASE, reg); return regmap_write(palmas->regmap[slave], addr, data); }
static int palmas_rtc_read_block(void *mfd, u8 *dest, u8 reg, int no_regs) { struct palmas *palmas = mfd; int slave; unsigned int addr; slave = PALMAS_BASE_TO_SLAVE(PALMAS_RTC_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_RTC_BASE, reg); return regmap_bulk_read(palmas->regmap[slave], addr, dest, no_regs); }
static void palmas_power_off(void) { unsigned int addr; int ret, slave; u8 powerhold_mask; struct device_node *np = palmas_dev->dev->of_node; if (of_property_read_bool(np, "ti,palmas-override-powerhold")) { addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD2); slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); if (of_device_is_compatible(np, "ti,tps65917")) powerhold_mask = TPS65917_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK; else powerhold_mask = PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK; ret = regmap_update_bits(palmas_dev->regmap[slave], addr, powerhold_mask, 0); if (ret) dev_err(palmas_dev->dev, "Unable to write PRIMARY_SECONDARY_PAD2 %d\n", ret); } slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_DEV_CTRL); ret = regmap_update_bits( palmas_dev->regmap[slave], addr, PALMAS_DEV_CTRL_DEV_ON, 0); if (ret) pr_err("%s: Unable to write to DEV_CTRL_DEV_ON: %d\n", __func__, ret); }
static int palmas_rtc_write_block(void *mfd, u8 *data, u8 reg, int no_regs) { struct palmas *palmas = mfd; int slave; unsigned int addr; slave = PALMAS_BASE_TO_SLAVE(PALMAS_RTC_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_RTC_BASE, reg); /* twl added extra byte on beginning of block data */ if (no_regs > 1) data++; return regmap_raw_write(palmas->regmap[slave], addr, data, no_regs); }
static void palmas_power_off(void) { unsigned int addr; int ret, slave; if (!palmas_dev) return; slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_DEV_CTRL); ret = regmap_update_bits( palmas_dev->regmap[slave], addr, PALMAS_DEV_CTRL_DEV_ON, 0); if (ret) pr_err("%s: Unable to write to DEV_CTRL_DEV_ON: %d\n", __func__, ret); }
static int tps65917_smps_registration(struct palmas_pmic *pmic, struct palmas_pmic_driver_data *ddata, struct palmas_pmic_platform_data *pdata, const char *pdev_name, struct regulator_config config) { int id, ret; unsigned int addr, reg; struct regulator_dev *rdev; struct palmas_reg_init *reg_init; struct palmas_regs_info *rinfo; struct regulator_desc *desc; for (id = ddata->smps_start; id <= ddata->smps_end; id++) { /* * Miss out regulators which are not available due * to slaving configurations. */ desc = &pmic->desc[id]; desc->n_linear_ranges = 3; if ((id == TPS65917_REG_SMPS2) && pmic->smps12) continue; /* Initialise sleep/init values from platform data */ if (pdata && pdata->reg_init[id]) { reg_init = pdata->reg_init[id]; ret = palmas_smps_init(pmic->palmas, id, reg_init); if (ret) return ret; } else { reg_init = NULL; } rinfo = &ddata->palmas_regs_info[id]; /* Register the regulators */ desc->name = rinfo->name; desc->id = id; /* * Read and store the RANGE bit for later use * This must be done before regulator is probed, * otherwise we error in probe with unsupportable * ranges. Read the current smps mode for later use. */ addr = rinfo->vsel_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret) return ret; if (reg & TPS65917_SMPS1_VOLTAGE_RANGE) pmic->range[id] = 1; if (pmic->range[id]) desc->linear_ranges = smps_high_ranges; else desc->linear_ranges = smps_low_ranges; if (reg_init && reg_init->roof_floor) desc->ops = &tps65917_ops_ext_control_smps; else desc->ops = &tps65917_ops_smps; desc->n_voltages = PALMAS_SMPS_NUM_VOLTAGES; desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, rinfo->vsel_addr); desc->vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK; desc->ramp_delay = 2500; /* Read the smps mode for later use. */ addr = rinfo->ctrl_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret) return ret; pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, rinfo->ctrl_addr); desc->enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; /* set_mode overrides this value */ desc->enable_val = SMPS_CTRL_MODE_ON; desc->type = REGULATOR_VOLTAGE; desc->owner = THIS_MODULE; if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; desc->supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; rdev = devm_regulator_register(pmic->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(pmic->dev, "failed to register %s regulator\n", pdev_name); return PTR_ERR(rdev); } /* Save regulator for cleanup */ pmic->rdev[id] = rdev; } return 0; }
static int palmas_smps_registration(struct palmas_pmic *pmic, struct palmas_pmic_driver_data *ddata, struct palmas_pmic_platform_data *pdata, const char *pdev_name, struct regulator_config config) { int id, ret; unsigned int addr, reg; struct regulator_dev *rdev; struct palmas_reg_init *reg_init; struct palmas_regs_info *rinfo; struct regulator_desc *desc; for (id = ddata->smps_start; id <= ddata->smps_end; id++) { bool ramp_delay_support = false; /* * Miss out regulators which are not available due * to slaving configurations. */ switch (id) { case PALMAS_REG_SMPS12: case PALMAS_REG_SMPS3: if (pmic->smps123) continue; if (id == PALMAS_REG_SMPS12) ramp_delay_support = true; break; case PALMAS_REG_SMPS123: if (!pmic->smps123) continue; ramp_delay_support = true; break; case PALMAS_REG_SMPS45: case PALMAS_REG_SMPS7: if (pmic->smps457) continue; if (id == PALMAS_REG_SMPS45) ramp_delay_support = true; break; case PALMAS_REG_SMPS457: if (!pmic->smps457) continue; ramp_delay_support = true; break; case PALMAS_REG_SMPS10_OUT1: case PALMAS_REG_SMPS10_OUT2: if (!PALMAS_PMIC_HAS(pmic->palmas, SMPS10_BOOST)) continue; } rinfo = &ddata->palmas_regs_info[id]; desc = &pmic->desc[id]; if ((id == PALMAS_REG_SMPS6) || (id == PALMAS_REG_SMPS8)) ramp_delay_support = true; if (ramp_delay_support) { addr = rinfo->tstep_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret < 0) { dev_err(pmic->dev, "reading TSTEP reg failed: %d\n", ret); return ret; } desc->ramp_delay = palmas_smps_ramp_delay[reg & 0x3]; pmic->ramp_delay[id] = desc->ramp_delay; } /* Initialise sleep/init values from platform data */ if (pdata && pdata->reg_init[id]) { reg_init = pdata->reg_init[id]; ret = palmas_smps_init(pmic->palmas, id, reg_init); if (ret) return ret; } else { reg_init = NULL; } /* Register the regulators */ desc->name = rinfo->name; desc->id = id; switch (id) { case PALMAS_REG_SMPS10_OUT1: case PALMAS_REG_SMPS10_OUT2: desc->n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; desc->ops = &palmas_ops_smps10; desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, PALMAS_SMPS10_CTRL); desc->vsel_mask = SMPS10_VSEL; desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, PALMAS_SMPS10_CTRL); if (id == PALMAS_REG_SMPS10_OUT1) desc->enable_mask = SMPS10_SWITCH_EN; else desc->enable_mask = SMPS10_BOOST_EN; desc->bypass_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, PALMAS_SMPS10_CTRL); desc->bypass_mask = SMPS10_BYPASS_EN; desc->min_uV = 3750000; desc->uV_step = 1250000; break; default: /* * Read and store the RANGE bit for later use * This must be done before regulator is probed, * otherwise we error in probe with unsupportable * ranges. Read the current smps mode for later use. */ addr = rinfo->vsel_addr; desc->n_linear_ranges = 3; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret) return ret; if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) pmic->range[id] = 1; if (pmic->range[id]) desc->linear_ranges = smps_high_ranges; else desc->linear_ranges = smps_low_ranges; if (reg_init && reg_init->roof_floor) desc->ops = &palmas_ops_ext_control_smps; else desc->ops = &palmas_ops_smps; desc->n_voltages = PALMAS_SMPS_NUM_VOLTAGES; desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, rinfo->vsel_addr); desc->vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK; /* Read the smps mode for later use. */ addr = rinfo->ctrl_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret) return ret; pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, rinfo->ctrl_addr); desc->enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; /* set_mode overrides this value */ desc->enable_val = SMPS_CTRL_MODE_ON; } desc->type = REGULATOR_VOLTAGE; desc->owner = THIS_MODULE; if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; desc->supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; rdev = devm_regulator_register(pmic->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(pmic->dev, "failed to register %s regulator\n", pdev_name); return PTR_ERR(rdev); } /* Save regulator for cleanup */ pmic->rdev[id] = rdev; } return 0; }
static int tps65917_ldo_registration(struct palmas_pmic *pmic, struct palmas_pmic_driver_data *ddata, struct palmas_pmic_platform_data *pdata, const char *pdev_name, struct regulator_config config) { int id, ret; struct regulator_dev *rdev; struct palmas_reg_init *reg_init; struct palmas_regs_info *rinfo; struct regulator_desc *desc; for (id = ddata->ldo_begin; id < ddata->max_reg; id++) { if (pdata && pdata->reg_init[id]) reg_init = pdata->reg_init[id]; else reg_init = NULL; /* Miss out regulators which are not available due * to alternate functions. */ rinfo = &ddata->palmas_regs_info[id]; /* Register the regulators */ desc = &pmic->desc[id]; desc->name = rinfo->name; desc->id = id; desc->type = REGULATOR_VOLTAGE; desc->owner = THIS_MODULE; if (id < TPS65917_REG_REGEN1) { desc->n_voltages = PALMAS_LDO_NUM_VOLTAGES; if (reg_init && reg_init->roof_floor) desc->ops = &palmas_ops_ext_control_ldo; else desc->ops = &tps65917_ops_ldo; desc->min_uV = 900000; desc->uV_step = 50000; desc->linear_min_sel = 1; desc->enable_time = 500; desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, rinfo->vsel_addr); desc->vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, rinfo->ctrl_addr); desc->enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; /* * To be confirmed. Discussion on going with PMIC Team. * It is of the order of ~60mV/uS. */ desc->ramp_delay = 2500; if (id == TPS65917_REG_LDO1 || id == TPS65917_REG_LDO2) { desc->ops = &tps65917_ops_ldo_1_2; desc->bypass_reg = desc->enable_reg; desc->bypass_mask = TPS65917_LDO1_CTRL_BYPASS_EN; } } else { desc->n_voltages = 1; if (reg_init && reg_init->roof_floor) desc->ops = &palmas_ops_ext_control_extreg; else desc->ops = &palmas_ops_extreg; desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, rinfo->ctrl_addr); desc->enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE; } if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; desc->supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; rdev = devm_regulator_register(pmic->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(pmic->dev, "failed to register %s regulator\n", pdev_name); return PTR_ERR(rdev); } /* Save regulator for cleanup */ pmic->rdev[id] = rdev; /* Initialise sleep/init values from platform data */ if (pdata) { reg_init = pdata->reg_init[id]; if (reg_init) { if (id < TPS65917_REG_REGEN1) ret = palmas_ldo_init(pmic->palmas, id, reg_init); else ret = palmas_extreg_init(pmic->palmas, id, reg_init); if (ret) return ret; } } } return 0; }
static int palmas_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct palmas *palmas; struct palmas_platform_data *pdata; struct device_node *node = i2c->dev.of_node; int ret = 0, i; unsigned int reg, addr; int slave; struct mfd_cell *children; pdata = dev_get_platdata(&i2c->dev); if (node && !pdata) { pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; palmas_dt_to_pdata(node, pdata); } if (!pdata) return -EINVAL; palmas = devm_kzalloc(&i2c->dev, sizeof(struct palmas), GFP_KERNEL); if (palmas == NULL) return -ENOMEM; i2c_set_clientdata(i2c, palmas); palmas->dev = &i2c->dev; palmas->id = id->driver_data; palmas->irq = i2c->irq; for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { if (i == 0) palmas->i2c_clients[i] = i2c; else { palmas->i2c_clients[i] = i2c_new_dummy(i2c->adapter, i2c->addr + i); if (!palmas->i2c_clients[i]) { dev_err(palmas->dev, "can't attach client %d\n", i); ret = -ENOMEM; goto err; } } palmas->regmap[i] = devm_regmap_init_i2c(palmas->i2c_clients[i], &palmas_regmap_config[i]); if (IS_ERR(palmas->regmap[i])) { ret = PTR_ERR(palmas->regmap[i]); dev_err(palmas->dev, "Failed to allocate regmap %d, err: %d\n", i, ret); goto err; } } /* Change IRQ into clear on read mode for efficiency */ slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); reg = PALMAS_INT_CTRL_INT_CLEAR; regmap_write(palmas->regmap[slave], addr, reg); ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip, &palmas->irq_data); if (ret < 0) goto err; slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD1); if (pdata->mux_from_pdata) { reg = pdata->pad1; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err_irq; } if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0)) palmas->gpio_muxed |= PALMAS_GPIO_0_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_1_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->led_muxed |= PALMAS_LED1_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM1_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_2_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->led_muxed |= PALMAS_LED2_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM2_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3)) palmas->gpio_muxed |= PALMAS_GPIO_3_MUXED; addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD2); if (pdata->mux_from_pdata) { reg = pdata->pad2; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err_irq; } if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4)) palmas->gpio_muxed |= PALMAS_GPIO_4_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_5_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6)) palmas->gpio_muxed |= PALMAS_GPIO_6_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_7_MUXED; dev_info(palmas->dev, "Muxing GPIO %x, PWM %x, LED %x\n", palmas->gpio_muxed, palmas->pwm_muxed, palmas->led_muxed); reg = pdata->power_ctrl; slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_POWER_CTRL); ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; /* * If we are probing with DT do this the DT way and return here * otherwise continue and add devices using mfd helpers. */ if (node) { ret = of_platform_populate(node, NULL, NULL, &i2c->dev); if (ret < 0) goto err_irq; else return ret; } children = kmemdup(palmas_children, sizeof(palmas_children), GFP_KERNEL); if (!children) { ret = -ENOMEM; goto err_irq; } children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata; children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata); children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata; children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata); children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata; children[PALMAS_RESOURCE_ID].pdata_size = sizeof(*pdata->resource_pdata); children[PALMAS_USB_ID].platform_data = pdata->usb_pdata; children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata); children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata; children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata); ret = mfd_add_devices(palmas->dev, -1, children, ARRAY_SIZE(palmas_children), NULL, 0, regmap_irq_get_domain(palmas->irq_data)); kfree(children); if (ret < 0) goto err_devices; return ret; err_devices: mfd_remove_devices(palmas->dev); err_irq: regmap_del_irq_chip(palmas->irq, palmas->irq_data); err: return ret; }
}, { .name = "palmas-pwm", .id = PALMAS_PWM_ID, }, { .name = "palmas-usb", .id = PALMAS_USB_ID, } }; static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = { { .reg_bits = 8, .val_bits = 8, .max_register = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD3), }, { .reg_bits = 8, .val_bits = 8, .max_register = PALMAS_BASE_TO_REG(PALMAS_GPADC_BASE, PALMAS_GPADC_SMPS_VSEL_MONITORING), }, { .reg_bits = 8, .val_bits = 8, .max_register = PALMAS_BASE_TO_REG(PALMAS_TRIM_GPADC_BASE, PALMAS_GPADC_TRIM16), }, };
}, }; static bool is_volatile_palma_func_reg(struct device *dev, unsigned int reg) { if ((reg >= (PALMAS_SMPS12_CTRL + 0x20)) && (reg <= (PALMAS_SMPS9_VOLTAGE + 0x20))) return false; return true; } static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = { { .reg_bits = 8, .val_bits = 8, .max_register = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD4), .volatile_reg = is_volatile_palma_func_reg, .cache_type = REGCACHE_RBTREE, }, { .reg_bits = 8, .val_bits = 8, .max_register = PALMAS_BASE_TO_REG(PALMAS_GPADC_BASE, PALMAS_GPADC_SMPS_VSEL_MONITORING), }, { .reg_bits = 8, .val_bits = 8, .max_register = PALMAS_BASE_TO_REG(PALMAS_TRIM_GPADC_BASE, PALMAS_GPADC_TRIM16), },
static int palmas_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct palmas *palmas; struct palmas_platform_data *pdata; struct device_node *node = i2c->dev.of_node; int ret = 0, i; unsigned int reg, addr, *features; int slave; const struct of_device_id *match; pdata = dev_get_platdata(&i2c->dev); if (node && !pdata) { pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; palmas_dt_to_pdata(i2c, pdata); } if (!pdata) return -EINVAL; palmas = devm_kzalloc(&i2c->dev, sizeof(struct palmas), GFP_KERNEL); if (palmas == NULL) return -ENOMEM; i2c_set_clientdata(i2c, palmas); palmas->dev = &i2c->dev; palmas->irq = i2c->irq; match = of_match_device(of_match_ptr(of_palmas_match_tbl), &i2c->dev); if (!match) return -ENODATA; features = (unsigned int *)match->data; palmas->features = *features; for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { if (i == 0) palmas->i2c_clients[i] = i2c; else { palmas->i2c_clients[i] = i2c_new_dummy(i2c->adapter, i2c->addr + i); if (!palmas->i2c_clients[i]) { dev_err(palmas->dev, "can't attach client %d\n", i); ret = -ENOMEM; goto err; } palmas->i2c_clients[i]->dev.of_node = of_node_get(node); } palmas->regmap[i] = devm_regmap_init_i2c(palmas->i2c_clients[i], &palmas_regmap_config[i]); if (IS_ERR(palmas->regmap[i])) { ret = PTR_ERR(palmas->regmap[i]); dev_err(palmas->dev, "Failed to allocate regmap %d, err: %d\n", i, ret); goto err; } } if (!palmas->irq) { dev_warn(palmas->dev, "IRQ missing: skipping irq request\n"); goto no_irq; } /* Change interrupt line output polarity */ if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH) reg = PALMAS_POLARITY_CTRL_INT_POLARITY; else reg = 0; ret = palmas_update_bits(palmas, PALMAS_PU_PD_OD_BASE, PALMAS_POLARITY_CTRL, PALMAS_POLARITY_CTRL_INT_POLARITY, reg); if (ret < 0) { dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret); goto err; } /* Change IRQ into clear on read mode for efficiency */ slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); reg = PALMAS_INT_CTRL_INT_CLEAR; regmap_write(palmas->regmap[slave], addr, reg); ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip, &palmas->irq_data); if (ret < 0) goto err; no_irq: slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD1); if (pdata->mux_from_pdata) { reg = pdata->pad1; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err_irq; } if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0)) palmas->gpio_muxed |= PALMAS_GPIO_0_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_1_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->led_muxed |= PALMAS_LED1_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM1_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_2_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->led_muxed |= PALMAS_LED2_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM2_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3)) palmas->gpio_muxed |= PALMAS_GPIO_3_MUXED; addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD2); if (pdata->mux_from_pdata) { reg = pdata->pad2; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err_irq; } if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4)) palmas->gpio_muxed |= PALMAS_GPIO_4_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_5_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6)) palmas->gpio_muxed |= PALMAS_GPIO_6_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_7_MUXED; dev_info(palmas->dev, "Muxing GPIO %x, PWM %x, LED %x\n", palmas->gpio_muxed, palmas->pwm_muxed, palmas->led_muxed); reg = pdata->power_ctrl; slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_POWER_CTRL); ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; /* * If we are probing with DT do this the DT way and return here * otherwise continue and add devices using mfd helpers. */ if (node) { ret = of_platform_populate(node, NULL, NULL, &i2c->dev); if (ret < 0) goto err_irq; else return ret; } return ret; err_irq: regmap_del_irq_chip(palmas->irq, palmas->irq_data); err: return ret; }
static int palmas_ldo_registration(struct palmas_pmic *pmic, struct palmas_pmic_driver_data *ddata, struct palmas_pmic_platform_data *pdata, const char *pdev_name, struct regulator_config config) { int id, ret; struct regulator_dev *rdev; struct palmas_reg_init *reg_init; struct palmas_regs_info *rinfo; struct regulator_desc *desc; for (id = ddata->ldo_begin; id < ddata->max_reg; id++) { if (pdata && pdata->reg_init[id]) reg_init = pdata->reg_init[id]; else reg_init = NULL; rinfo = &ddata->palmas_regs_info[id]; /* Miss out regulators which are not available due * to alternate functions. */ /* Register the regulators */ desc = &pmic->desc[id]; desc->name = rinfo->name; desc->id = id; desc->type = REGULATOR_VOLTAGE; desc->owner = THIS_MODULE; if (id < PALMAS_REG_REGEN1) { desc->n_voltages = PALMAS_LDO_NUM_VOLTAGES; if (reg_init && reg_init->roof_floor) desc->ops = &palmas_ops_ext_control_ldo; else desc->ops = &palmas_ops_ldo; desc->min_uV = 900000; desc->uV_step = 50000; desc->linear_min_sel = 1; desc->enable_time = 500; desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, rinfo->vsel_addr); desc->vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, rinfo->ctrl_addr); desc->enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; /* Check if LDO8 is in tracking mode or not */ if (pdata && (id == PALMAS_REG_LDO8) && pdata->enable_ldo8_tracking) { palmas_enable_ldo8_track(pmic->palmas); desc->min_uV = 450000; desc->uV_step = 25000; } /* LOD6 in vibrator mode will have enable time 2000us */ if (pdata && pdata->ldo6_vibrator && (id == PALMAS_REG_LDO6)) desc->enable_time = 2000; if (id == PALMAS_REG_LDO9) { desc->ops = &palmas_ops_ldo9; desc->bypass_reg = desc->enable_reg; desc->bypass_mask = PALMAS_LDO9_CTRL_LDO_BYPASS_EN; } } else { if (!ddata->has_regen3 && id == PALMAS_REG_REGEN3) continue; desc->n_voltages = 1; if (reg_init && reg_init->roof_floor) desc->ops = &palmas_ops_ext_control_extreg; else desc->ops = &palmas_ops_extreg; desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, rinfo->ctrl_addr); desc->enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE; } if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; desc->supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; rdev = devm_regulator_register(pmic->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(pmic->dev, "failed to register %s regulator\n", pdev_name); return PTR_ERR(rdev); } /* Save regulator for cleanup */ pmic->rdev[id] = rdev; /* Initialise sleep/init values from platform data */ if (pdata) { reg_init = pdata->reg_init[id]; if (reg_init) { if (id <= ddata->ldo_end) ret = palmas_ldo_init(pmic->palmas, id, reg_init); else ret = palmas_extreg_init(pmic->palmas, id, reg_init); if (ret) return ret; } } } return 0; }
static int __devinit palmas_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct palmas *palmas; struct palmas_platform_data *mfd_platform_data; int ret = 0, i; unsigned int reg, addr; int slave; char *rname; mfd_platform_data = dev_get_platdata(&i2c->dev); if (!mfd_platform_data) return -EINVAL; palmas = kzalloc(sizeof(struct palmas), GFP_KERNEL); if (palmas == NULL) return -ENOMEM; i2c_set_clientdata(i2c, palmas); palmas->dev = &i2c->dev; palmas->id = id->driver_data; ret = irq_alloc_descs(-1, 0, PALMAS_NUM_IRQ, 0); if (ret < 0) { dev_err(&i2c->dev, "failed to allocate IRQ descs\n"); goto err; } palmas->irq = i2c->irq; palmas->irq_base = ret; palmas->irq_end = ret + PALMAS_NUM_IRQ; for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { if (i == 0) palmas->i2c_clients[i] = i2c; else { palmas->i2c_clients[i] = i2c_new_dummy(i2c->adapter, i2c->addr + i); if (!palmas->i2c_clients[i]) { dev_err(palmas->dev, "can't attach client %d\n", i); ret = -ENOMEM; goto err; } } palmas->regmap[i] = regmap_init_i2c(palmas->i2c_clients[i], &palmas_regmap_config[i]); if (IS_ERR(palmas->regmap[i])) { ret = PTR_ERR(palmas->regmap[i]); dev_err(palmas->dev, "Failed to allocate register map " "No: %d, because: %d\n", i, ret); goto err; } } ret = palmas_irq_init(palmas); if (ret < 0) goto err; slave = PALMAS_BASE_TO_SLAVE(PALMAS_DESIGNREV_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_DESIGNREV_BASE, 0); /* * Revision either * PALMAS_REV_ES1_0 or * PALMAS_REV_ES2_0 or * PALMAS_REV_ES2_1 */ ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err; palmas->revision = reg; switch (palmas->revision) { case PALMAS_REV_ES1_0: rname = "ES 1.0"; break; case PALMAS_REV_ES2_0: rname = "ES 2.0"; break; case PALMAS_REV_ES2_1: rname = "ES 2.1"; break; default: rname = "unknown"; break; } dev_info(palmas->dev, "%s %s detected\n", id->name, rname); slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD1); if (mfd_platform_data->mux_from_pdata) { reg = mfd_platform_data->pad1; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err; } if (!(reg & PRIMARY_SECONDARY_PAD1_GPIO_0)) palmas->gpio_muxed |= PALMAS_GPIO_0_MUXED; if (!(reg & PRIMARY_SECONDARY_PAD1_GPIO_1_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_1_MUXED; else if ((reg & PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (2 << PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->led_muxed |= PALMAS_LED1_MUXED; else if ((reg & PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (3 << PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM1_MUXED; if (!(reg & PRIMARY_SECONDARY_PAD1_GPIO_2_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_2_MUXED; else if ((reg & PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (2 << PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->led_muxed |= PALMAS_LED2_MUXED; else if ((reg & PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (3 << PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM2_MUXED; if (!(reg & PRIMARY_SECONDARY_PAD1_GPIO_3)) palmas->gpio_muxed |= PALMAS_GPIO_3_MUXED; addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD2); if (mfd_platform_data->mux_from_pdata) { reg = mfd_platform_data->pad2; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err; } if (!(reg & PRIMARY_SECONDARY_PAD2_GPIO_4)) palmas->gpio_muxed |= PALMAS_GPIO_4_MUXED; if (!(reg & PRIMARY_SECONDARY_PAD2_GPIO_5_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_5_MUXED; if (!(reg & PRIMARY_SECONDARY_PAD2_GPIO_6)) palmas->gpio_muxed |= PALMAS_GPIO_6_MUXED; if (!(reg & PRIMARY_SECONDARY_PAD2_GPIO_7_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_7_MUXED; dev_info(palmas->dev, "Muxing GPIO %x, PWM %x, LED %x\n", palmas->gpio_muxed, palmas->pwm_muxed, palmas->led_muxed); reg = mfd_platform_data->power_ctrl; slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_POWER_CTRL); ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err; palmas_rtc_init(palmas); ret = mfd_add_devices(palmas->dev, -1, palmas_children, ARRAY_SIZE(palmas_children), NULL, palmas->irq_base); if (ret < 0) goto err; return ret; err: mfd_remove_devices(palmas->dev); kfree(palmas); return ret; }