// kmj_el15.pm8901_patch int pm8901_preload_dVdd(void) { int rc; u8 reg; if (pmic_chip == NULL) { pr_err("%s: Error: PMIC 8901 driver has not probed\n", __func__); return -ENODEV; } reg = 0x0F; rc = ssbi_write(pmic_chip->dev, 0x0BD, ®, 1); if (rc) pr_err("%s: ssbi_write failed for 0x0BD, rc=%d\n", __func__, rc); reg = 0xB4; rc = ssbi_write(pmic_chip->dev, 0x001, ®, 1); if (rc) pr_err("%s: ssbi_write failed for 0x001, rc=%d\n", __func__, rc); pr_info("%s: dVdd preloaded\n", __func__); return rc; }
int pm8058_misc_control(struct pm8058_chip *chip, int mask, int flag) { int rc; u8 misc; unsigned long irqsave; if (chip == NULL) chip = pmic_chip; if (chip == NULL) return -ENODEV; spin_lock_irqsave(&chip->pm_lock, irqsave); rc = ssbi_read(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1); if (rc) { pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__, SSBI_REG_ADDR_MISC, rc); goto get_out; } misc &= ~mask; misc |= flag; rc = ssbi_write(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1); if (rc) { pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n", __func__, SSBI_REG_ADDR_MISC, misc, rc); goto get_out; } get_out: spin_unlock_irqrestore(&chip->pm_lock, irqsave); return rc; }
static int pm8921_writeb(const struct device *dev, u16 addr, u8 val) { const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; return ssbi_write(pmic->dev->parent, addr, &val, 1); }
static int pm8058_masked_write(u16 addr, u8 val, u8 mask) { int rc; u8 reg; if (pmic_chip == NULL) return -ENODEV; rc = ssbi_read(pmic_chip->dev, addr, ®, 1); if (rc) { pr_err("%s: ssbi_read(0x%03X) failed: rc=%d\n", __func__, addr, rc); goto done; } reg &= ~mask; reg |= val & mask; rc = ssbi_write(pmic_chip->dev, addr, ®, 1); if (rc) pr_err("%s: ssbi_write(0x%03X)=0x%02X failed: rc=%d\n", __func__, addr, reg, rc); done: return rc; }
int pm8058_reset_pwr_off(int reset) { int rc; u8 pon; unsigned long irqsave; if (pmic_chip == NULL) return -ENODEV; spin_lock_irqsave(&pmic_chip->pm_lock, irqsave); rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_1, &pon, 1); if (rc) { pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__, SSBI_REG_ADDR_PON_CNTL_1, rc); goto get_out; } pon &= ~PM8058_PON_WD_EN_MASK; pon |= reset ? PM8058_PON_WD_EN_RESET : PM8058_PON_WD_EN_PWR_OFF; rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_1, &pon, 1); if (rc) { pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n", __func__, SSBI_REG_ADDR_PON_CNTL_1, pon, rc); goto get_out; } get_out: spin_unlock_irqrestore(&pmic_chip->pm_lock, irqsave); return rc; }
int pm8058_misc_control(struct pm8058_chip *chip, int mask, int flag) { int rc; u8 misc; if (chip == NULL) chip = pmic_chip; /* for calls from non child */ if (chip == NULL) return -ENODEV; mutex_lock(&chip->pm_lock); rc = ssbi_read(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1); if (rc) { pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__, SSBI_REG_ADDR_MISC, rc); goto get_out; } misc &= ~mask; misc |= flag; rc = ssbi_write(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1); if (rc) { pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n", __func__, SSBI_REG_ADDR_MISC, misc, rc); goto get_out; } get_out: mutex_unlock(&chip->pm_lock); return rc; }
int pm8058_write(struct pm8058_chip *chip, u16 addr, u8 *values, unsigned int len) { if (chip == NULL) return -EINVAL; return ssbi_write(chip->dev, addr, values, len); }
static int pm8921_write_buf(const struct device *dev, u16 addr, u8 *buf, int cnt) { const struct pm8xxx_drvdata *pm8921_drvdata = dev_get_drvdata(dev); const struct pm8921 *pmic = pm8921_drvdata->pm_chip_data; return ssbi_write(pmic->dev->parent, addr, buf, cnt); }
/* Internal functions */ static inline int pm8901_config_irq(struct pm8901_chip *chip, u8 *bp, u8 *cp) { int rc; rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1); if (rc) { pr_err("%s: ssbi_write: rc=%d (Select block)\n", __func__, rc); goto bail_out; } rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp, 1); if (rc) pr_err("%s: ssbi_write: rc=%d (Configure IRQ)\n", __func__, rc); bail_out: return rc; }
int pm8058_write(struct pm8058_chip *chip, u16 addr, u8 *values, unsigned int len) { int rc; unsigned long irqsave; if (chip == NULL) return -EINVAL; spin_lock_irqsave(&chip->pm_lock, irqsave); rc = ssbi_write(chip->dev, addr, values, len); spin_unlock_irqrestore(&chip->pm_lock, irqsave); return rc; }
int pm8058_irq_get_rt_status(struct pm8058_chip *chip, int irq) { int rc; u8 block, bits, bit; #ifdef CONFIG_MSM8X60_SSBI unsigned long irqsave; #endif if (chip == NULL || irq < chip->pdata.irq_base || irq >= chip->pdata.irq_base + MAX_PM_IRQ) return -EINVAL; irq -= chip->pdata.irq_base; block = irq / 8; bit = irq % 8; #ifdef CONFIG_MSM8X60_SSBI spin_lock_irqsave(&chip->pm_lock, irqsave); #else mutex_lock(&chip->pm_lock); #endif rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, &block, 1); if (rc) { pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n", __func__, rc); goto bail_out; } rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits, 1); if (rc) { pr_err("%s: FAIL ssbi_read(): rc=%d (Read RT Status)\n", __func__, rc); goto bail_out; } rc = (bits & (1 << bit)) ? 1 : 0; bail_out: #ifdef CONFIG_MSM8X60_SSBI spin_unlock_irqrestore(&chip->pm_lock, irqsave); #else mutex_unlock(&chip->pm_lock); #endif return rc; }
/* Helper Functions */ DEFINE_RATELIMIT_STATE(pm8058_msg_ratelimit, 60 * HZ, 10); static inline int pm8058_can_print(void) { return __ratelimit(&pm8058_msg_ratelimit); } #ifdef CONFIG_MSM8X60_SSBI #define ssbi_write(client, addr, buf, len) \ msm_ssbi_write(pmic_chip->id, addr, buf, len) #define ssbi_read(client, addr, buf, len) \ msm_ssbi_read(pmic_chip->id, addr, buf, len) #else /*CONFIG_MSM8X60_SSBI*/ static inline int ssbi_write(struct i2c_client *client, u16 addr, const u8 *buf, size_t len) { int rc; struct i2c_msg msg = { .addr = addr, .flags = 0x0, .buf = (u8 *)buf, .len = len, }; rc = i2c_transfer(client->adapter, &msg, 1); return (rc == 1) ? 0 : rc; } static inline int ssbi_read(struct i2c_client *client, u16 addr, u8 *buf, size_t len) { int rc; struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len, }; rc = i2c_transfer(client->adapter, &msg, 1); return (rc == 1) ? 0 : rc; } #endif/*CONFIG_MSM8X60_SSBI*/ static int pm8058_masked_write(u16 addr, u8 val, u8 mask) { int rc; u8 reg; #ifndef CONFIG_MACH_VERDI_LTE //[Puccini] QCT patch: SMPS actvie pull-down #ifdef CONFIG_MSM8X60_SSBI unsigned long irqsave; #endif #endif // !CONFIG_MACH_VERDI_LTE if (pmic_chip == NULL) return -ENODEV; #ifndef CONFIG_MACH_VERDI_LTE //[Puccini] QCT patch: SMPS actvie pull-down #ifdef CONFIG_MSM8X60_SSBI spin_lock_irqsave(&pmic_chip->pm_lock, irqsave); #else mutex_lock(&pmic_chip->pm_lock); #endif #endif // !CONFIG_MACH_VERDI_LTE rc = ssbi_read(pmic_chip->dev, addr, ®, 1); if (rc) { pr_err("%s: ssbi_read(0x%03X) failed: rc=%d\n", __func__, addr, rc); goto done; } reg &= ~mask; reg |= val & mask; rc = ssbi_write(pmic_chip->dev, addr, ®, 1); if (rc) pr_err("%s: ssbi_write(0x%03X)=0x%02X failed: rc=%d\n", __func__, addr, reg, rc); done: #ifndef CONFIG_MACH_VERDI_LTE //[Puccini] QCT patch: SMPS actvie pull-down #ifdef CONFIG_MSM8X60_SSBI spin_unlock_irqrestore(&pmic_chip->pm_lock, irqsave); #else mutex_unlock(&pmic_chip->pm_lock); #endif #endif // !CONFIG_MACH_VERDI_LTE return rc; }
/* External APIs */ int pm8058_rev(struct pm8058_chip *chip) { if (chip == NULL) return -EINVAL; return chip->revision; } EXPORT_SYMBOL(pm8058_rev); int pm8058_irq_get_rt_status(struct pm8058_chip *chip, int irq) { int rc; u8 block, bits, bit; #ifdef CONFIG_MSM8X60_SSBI unsigned long irqsave; #endif if (chip == NULL || irq < chip->pdata.irq_base || irq >= chip->pdata.irq_base + MAX_PM_IRQ) return -EINVAL; irq -= chip->pdata.irq_base; block = irq / 8; bit = irq % 8; #ifdef CONFIG_MSM8X60_SSBI spin_lock_irqsave(&chip->pm_lock, irqsave); #else mutex_lock(&chip->pm_lock); #endif rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, &block, 1); if (rc) { pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n", __func__, rc); goto bail_out; } rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits, 1); if (rc) { pr_err("%s: FAIL ssbi_read(): rc=%d (Read RT Status)\n", __func__, rc); goto bail_out; } rc = (bits & (1 << bit)) ? 1 : 0; bail_out: #ifdef CONFIG_MSM8X60_SSBI spin_unlock_irqrestore(&chip->pm_lock, irqsave); #else mutex_unlock(&chip->pm_lock); #endif return rc; } EXPORT_SYMBOL(pm8058_irq_get_rt_status); #ifdef CONFIG_MSM8X60_SSBI int pm8058_read(struct pm8058_chip *chip, u16 addr, u8 *values, unsigned int len) { int rc; unsigned long irqsave; if (chip == NULL) return -EINVAL; spin_lock_irqsave(&chip->pm_lock, irqsave); rc = ssbi_read(chip->dev, addr, values, len); spin_unlock_irqrestore(&chip->pm_lock, irqsave); return rc; } EXPORT_SYMBOL(pm8058_read); int pm8058_write(struct pm8058_chip *chip, u16 addr, u8 *values, unsigned int len) { int rc; unsigned long irqsave; if (chip == NULL) return -EINVAL; spin_lock_irqsave(&chip->pm_lock, irqsave); rc = ssbi_write(chip->dev, addr, values, len); spin_unlock_irqrestore(&chip->pm_lock, irqsave); return rc; } EXPORT_SYMBOL(pm8058_write); #else int pm8058_read(struct pm8058_chip *chip, u16 addr, u8 *values, unsigned int len) { if (chip == NULL) return -EINVAL; return ssbi_read(chip->dev, addr, values, len); } EXPORT_SYMBOL(pm8058_read); int pm8058_write(struct pm8058_chip *chip, u16 addr, u8 *values, unsigned int len) { if (chip == NULL) return -EINVAL; return ssbi_write(chip->dev, addr, values, len); } EXPORT_SYMBOL(pm8058_write); #endif /*CONFIG_MSM8X60_SSBI */ int pm8058_misc_control(struct pm8058_chip *chip, int mask, int flag) { int rc; u8 misc; #ifdef CONFIG_MSM8X60_SSBI unsigned long irqsave; #endif if (chip == NULL) chip = pmic_chip; /* for calls from non child */ if (chip == NULL) return -ENODEV; #ifdef CONFIG_MSM8X60_SSBI spin_lock_irqsave(&chip->pm_lock, irqsave); #else mutex_lock(&chip->pm_lock); #endif rc = ssbi_read(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1); if (rc) { pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__, SSBI_REG_ADDR_MISC, rc); goto get_out; } misc &= ~mask; misc |= flag; rc = ssbi_write(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1); if (rc) { pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n", __func__, SSBI_REG_ADDR_MISC, misc, rc); goto get_out; } get_out: #ifdef CONFIG_MSM8X60_SSBI spin_unlock_irqrestore(&chip->pm_lock, irqsave); #else mutex_unlock(&chip->pm_lock); #endif return rc; }
int pm8901_reset_pwr_off(int reset) { int rc = 0, i; u8 pmr; u8 pmr_addr[4] = { SSBI_REG_ADDR_S2_PMR, SSBI_REG_ADDR_S3_PMR, SSBI_REG_ADDR_S4_PMR, SSBI_REG_ADDR_S1_PMR, }; if (pmic_chip == NULL) return -ENODEV; /* Turn off regulators S1, S2, S3, S4 when shutting down. */ if (!reset) { for (i = 0; i < 4; i++) { rc = ssbi_read(pmic_chip->dev, pmr_addr[i], &pmr, 1); if (rc) { pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__, pmr_addr[i], rc); goto get_out; } pmr &= ~REGULATOR_PMR_STATE_MASK; pmr |= REGULATOR_PMR_STATE_OFF; rc = ssbi_write(pmic_chip->dev, pmr_addr[i], &pmr, 1); if (rc) { pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d" "\n", __func__, pmr_addr[i], pmr, rc); goto get_out; } mdelay(DELAY_AFTER_REG_DISABLE_MS); } } get_out: mdelay(DELAY_BEFORE_SHUTDOWN_MS); return rc; }
int pm8901_reset_pwr_off(int reset) { int rc = 0, i; u8 pmr; u8 pmr_addr[4] = { SSBI_REG_ADDR_S2_PMR, SSBI_REG_ADDR_S3_PMR, SSBI_REG_ADDR_S4_PMR, SSBI_REG_ADDR_S1_PMR, }; if (pmic_chip == NULL) return -ENODEV; /* Turn off regulators S1, S2, S3, S4 when shutting down. */ if (!reset) { for (i = 0; i < 4; i++) { rc = ssbi_read(pmic_chip->dev, pmr_addr[i], &pmr, 1); if (rc) { pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__, pmr_addr[i], rc); goto get_out; } pmr &= ~REGULATOR_PMR_STATE_MASK; pmr |= REGULATOR_PMR_STATE_OFF; rc = ssbi_write(pmic_chip->dev, pmr_addr[i], &pmr, 1); /* changed from 4 to 10 because S3B voltage fail in Q1LTE*/ mdelay(10); /* 10ms delay between regulator turn Off */ if (rc) { pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d" "\n", __func__, pmr_addr[i], pmr, rc); goto get_out; } } } get_out: return rc; }
static inline int pm8901_read_block(struct pm8901_chip *chip, u8 *bp, u8 *ip) { int rc; rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1); if (rc) { pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n", __func__, rc); *bp = 0; goto bail_out; } rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip, 1); if (rc) pr_err("%s: FAIL ssbi_read(): rc=%d (Read Status)\n", __func__, rc); bail_out: return rc; }
int pm8058_irq_get_rt_status(struct pm8058_chip *chip, int irq) { int rc; u8 block, bits, bit; if (chip == NULL || irq < chip->pdata.irq_base || irq >= chip->pdata.irq_base + MAX_PM_IRQ) return -EINVAL; irq -= chip->pdata.irq_base; block = irq / 8; bit = irq % 8; mutex_lock(&chip->pm_lock); rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, &block, 1); if (rc) { pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n", __func__, rc); goto bail_out; } rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits, 1); if (rc) { pr_err("%s: FAIL ssbi_read(): rc=%d (Read RT Status)\n", __func__, rc); goto bail_out; } rc = (bits & (1 << bit)) ? 1 : 0; bail_out: mutex_unlock(&chip->pm_lock); return rc; }
/* * Set an SMPS regulator to be disabled in its CTRL register, but enabled * in the master enable register. Also set it's pull down enable bit. * Take care to make sure that the output voltage doesn't change if switching * from advanced mode to legacy mode. */ static int disable_smps_locally_set_pull_down(u16 ctrl_addr, u16 test2_addr, u16 master_enable_addr, u8 master_enable_bit) { int rc = 0; u8 vref_sel, vlow_sel, band, vprog, bank, reg; if (pmic_chip == NULL) return -ENODEV; bank = REGULATOR_BANK_SEL(7); rc = ssbi_write(pmic_chip->dev, test2_addr, &bank, 1); if (rc) { pr_err("%s: FAIL ssbi_write(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = ssbi_read(pmic_chip->dev, test2_addr, ®, 1); if (rc) { pr_err("%s: FAIL pm8058_read(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } /* Check if in advanced mode. */ if ((reg & SMPS_ADVANCED_MODE_MASK) == SMPS_ADVANCED_MODE) { /* Determine current output voltage. */ rc = ssbi_read(pmic_chip->dev, ctrl_addr, ®, 1); if (rc) { pr_err("%s: FAIL pm8058_read(0x%03X): rc=%d\n", __func__, ctrl_addr, rc); goto done; } band = (reg & SMPS_ADVANCED_BAND_MASK) >> SMPS_ADVANCED_BAND_SHIFT; switch (band) { case 3: vref_sel = 0; vlow_sel = 0; break; case 2: vref_sel = SMPS_LEGACY_VREF_SEL; vlow_sel = 0; break; case 1: vref_sel = SMPS_LEGACY_VREF_SEL; vlow_sel = SMPS_LEGACY_VLOW_SEL; break; default: pr_err("%s: regulator already disabled\n", __func__); return -EPERM; } vprog = (reg & SMPS_ADVANCED_VPROG_MASK); /* Round up if fine step is in use. */ vprog = (vprog + 1) >> 1; if (vprog > SMPS_LEGACY_VPROG_MASK) vprog = SMPS_LEGACY_VPROG_MASK; /* Set VLOW_SEL bit. */ bank = REGULATOR_BANK_SEL(1); rc = ssbi_write(pmic_chip->dev, test2_addr, &bank, 1); if (rc) { pr_err("%s: FAIL ssbi_write(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8058_masked_write(test2_addr, REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(1) | vlow_sel, REGULATOR_BANK_WRITE | REGULATOR_BANK_MASK | SMPS_LEGACY_VLOW_SEL); if (rc) goto done; /* Switch to legacy mode */ bank = REGULATOR_BANK_SEL(7); rc = ssbi_write(pmic_chip->dev, test2_addr, &bank, 1); if (rc) { pr_err("%s: FAIL ssbi_write(0x%03X): rc=%d\n", __func__, test2_addr, rc); goto done; } rc = pm8058_masked_write(test2_addr, REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(7) | SMPS_LEGACY_MODE, REGULATOR_BANK_WRITE | REGULATOR_BANK_MASK | SMPS_ADVANCED_MODE_MASK); if (rc) goto done; /* Enable locally, enable pull down, keep voltage the same. */ rc = pm8058_masked_write(ctrl_addr, REGULATOR_ENABLE | REGULATOR_PULL_DOWN_EN | vref_sel | vprog, REGULATOR_ENABLE_MASK | REGULATOR_PULL_DOWN_MASK | SMPS_LEGACY_VREF_SEL | SMPS_LEGACY_VPROG_MASK); if (rc) goto done; }
static long ftr_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { unsigned int __user *argp = (unsigned int __user *) arg; struct ftr_dev_file_info *pdfi = (struct ftr_dev_file_info *) file->private_data; struct ftr_dev_node_info *pdev; if (pdfi->ftrid < 0 || pdfi->ftrid >= RFIC_DEVICE_NUM) return -EINVAL; pdev = ftr_dev_info + pdfi->ftrid; switch (cmd) { case RFIC_IOCTL_READ_REGISTER: { int ret = 0; unsigned int rficaddr; u8 value = 0; if (get_user(rficaddr, argp)) return -EFAULT; mutex_lock(&pdev->lock); if (((pdfi->ftrid == 1) || (pdfi->ftrid == 2)) && (rfbid < RF_TYPE_48)) { __raw_writel( pdev->busselect[RFIC_FTR_GET_BUS(rficaddr)], pdev->grfcctrladdr); mb(); } ret = ssbi_read(pdev->dev->parent, RFIC_FTR_GET_ADDR(rficaddr), &value, 1); mutex_unlock(&pdev->lock); if (ret) return ret; if (put_user(value, argp)) return -EFAULT; } break; case RFIC_IOCTL_WRITE_REGISTER: { int ret; struct rfic_write_register_param param; unsigned int rficaddr; u8 value; if (copy_from_user(¶m, argp, sizeof(param))) return -EFAULT; rficaddr = param.rficaddr; value = (u8) param.value; mutex_lock(&pdev->lock); if (((pdfi->ftrid == 1) || (pdfi->ftrid == 2)) && (rfbid < RF_TYPE_48)) { __raw_writel( pdev->busselect[RFIC_FTR_GET_BUS(rficaddr)], pdev->grfcctrladdr); mb(); } ret = ssbi_write(pdev->dev->parent, RFIC_FTR_GET_ADDR(rficaddr), &value, 1); mutex_unlock(&pdev->lock); if (ret) return ret; } break; case RFIC_IOCTL_WRITE_REGISTER_WITH_MASK: { int ret; struct rfic_write_register_mask_param param; unsigned int rficaddr; u8 value; if (copy_from_user(¶m, argp, sizeof(param))) return -EFAULT; rficaddr = param.rficaddr; mutex_lock(&pdev->lock); if (((pdfi->ftrid == 1) || (pdfi->ftrid == 2)) && (rfbid < RF_TYPE_48)) { __raw_writel( pdev->busselect[RFIC_FTR_GET_BUS(rficaddr)], pdev->grfcctrladdr); mb(); } ret = ssbi_read(pdev->dev->parent, RFIC_FTR_GET_ADDR(rficaddr), &value, 1); value &= (u8) ~param.mask; value |= (u8) (param.value & param.mask); ret = ssbi_write(pdev->dev->parent, RFIC_FTR_GET_ADDR(rficaddr), &value, 1); mutex_unlock(&pdev->lock); if (ret) return ret; } break; case RFIC_IOCTL_GPIO_SETTING: { struct rfic_gpio_param param; struct msm_gpiomux_config rf_config[MSM_MAX_GPIO]; struct gpiomux_setting rf_setting[MSM_MAX_GPIO]; struct gpio_alt_config *alt_config; int gp_size, i; void *pGP; if (pdfi->ftrid != 0) return -EINVAL; if (copy_from_user(¶m, argp, sizeof(param))) { pr_err("%s: cfu fail for param\n", __func__); return -EFAULT; } if ((param.num < 1) || (param.num > MSM_MAX_GPIO)) { pr_err("Invalid GPIO count %d\n", param.num); return -EINVAL; } gp_size = sizeof(struct gpio_alt_config) * param.num; pGP = kmalloc(gp_size, GFP_KERNEL); if (pGP == NULL) return -ENOMEM; if (copy_from_user(pGP, param.pArray, gp_size)) { pr_err("%s: cfu fail for pGP\n", __func__); kfree(pGP); return -EFAULT; } alt_config = (struct gpio_alt_config *)pGP; for (i = 0; i < param.num; i++) { rf_config[i].gpio = (unsigned)alt_config->gpio; rf_setting[i].func = alt_config->func; rf_setting[i].drv = alt_config->drv; rf_setting[i].pull = alt_config->pull; rf_setting[i].dir = alt_config->dir; rf_config[i].settings[GPIOMUX_ACTIVE] = &rf_setting[i]; rf_config[i].settings[GPIOMUX_SUSPENDED] = &rf_setting[i]; alt_config++; } msm_gpiomux_install(rf_config, param.num); kfree(pGP); } break; case RFIC_IOCTL_GET_GRFC: { struct rfic_grfc_param param; if (pdfi->ftrid != 0) return -EINVAL; if (copy_from_user(¶m, argp, sizeof(param))) return -EFAULT; if (param.grfcid >= RFIC_GRFC_REG_NUM) return -EINVAL; param.maskvalue = __raw_readl( grfc_base + 0x20 + param.grfcid * 4); param.ctrlvalue = __raw_readl( grfc_base + param.grfcid * 4); if (copy_to_user(argp, ¶m, sizeof(param))) return -EFAULT; } break; case RFIC_IOCTL_SET_GRFC: { struct rfic_grfc_param param; if (pdfi->ftrid != 0) return -EINVAL; if (copy_from_user(¶m, argp, sizeof(param))) return -EFAULT; if (param.grfcid >= RFIC_GRFC_REG_NUM) return -EINVAL; __raw_writel(0, grfc_base + 0x20 + param.grfcid * 4); __raw_writel(param.ctrlvalue, grfc_base + param.grfcid * 4); __raw_writel(param.maskvalue, grfc_base + 0x20 + param.grfcid * 4); mb(); } break; case RFIC_IOCTL_SET_WFM: { struct rfic_wfm_param param; unsigned int p_sum; if (pdfi->ftrid != 0) return -EINVAL; if (copy_from_user(¶m, argp, sizeof(param))) return -EFAULT; /* Check for integer overflow */ if (param.offset > UINT_MAX - param.num) return -EINVAL; p_sum = param.offset + param.num; if (p_sum < param.offset || p_sum < param.num) return -EINVAL; if (p_sum > RF_MAX_WF_SIZE) return -EINVAL; if (copy_from_user(wf_base + param.offset, param.pArray, param.num)) return -EFAULT; } break; case RFIC_IOCTL_SET_LDO: { unsigned int ldo; if (pdfi->ftrid != 0) { pr_err("%s: Invalid id %d\n", __func__, pdfi->ftrid); return -EINVAL; } if (get_user(ldo, argp)) { pr_err("%s: Invalid ldo %d\n", __func__, ldo); return -EFAULT; } switch (ldo) { case LDO11: if (rf_regulator_init(to_platform_device (pdev->dev), "vdd-1v3", 0) != 0) pr_err("%s: LDO11 fail\n", __func__); break; case LDO18: if (rf_regulator_init(to_platform_device (pdev->dev), "vdd-switch", 0) != 0) pr_err("%s: LDO18 fail\n", __func__); break; case LDO19: if (rf_regulator_init(to_platform_device (pdev->dev), "vdd-wtr", 0) != 0) pr_err("%s: LDO19 fail\n", __func__); break; case LDO23: if (rf_regulator_init(to_platform_device (pdev->dev), "vdd-ftr1", 1) != 0) pr_err("%s: LDO23 fail\n", __func__); break; case LDO25: if (rf_regulator_init(to_platform_device (pdev->dev), "vdd-ftr2", 1) != 0) pr_err("%s: LDO25 fail\n", __func__); break; case LDO26: if (rf_regulator_init(to_platform_device (pdev->dev), "vdd-1v8", 1) != 0) pr_err("%s: LDO26 fail\n", __func__); break; default: pr_err("%s: Unknown LDO\n", __func__); break; } } break; case RFIC_IOCTL_SET_BOARDID: { if (pdfi->ftrid != 0) return -EINVAL; if (get_user(rfbid, argp)) return -EFAULT; } break; case RFIC_IOCTL_GET_BOARDID: { if (pdfi->ftrid != 0) return -EINVAL; if (put_user(rfbid, argp)) return -EFAULT; } break; case RFIC_IOCTL_GET_PDM: { struct pdm_param param; void __iomem *pdmaddr; int num; if (copy_from_user(¶m, argp, sizeof(param))) { pr_err("%s: CFU\n", __func__); return -EFAULT; } if ((pdfi->ftrid != 0) || (param.num > 5)) { pr_err("%s: ftrid %d num =%d\n", __func__, pdfi->ftrid, param.num); return -EINVAL; } mutex_lock(&pdev->lock); if (param.num > 2) num = param.num + 1; else num = param.num; pdmaddr = pdm_base + PDM_1_1_CTL * num; param.enable = __raw_readl(pdmaddr); param.value = __raw_readl(pdmaddr + 4); mutex_unlock(&pdev->lock); if (copy_to_user(argp, ¶m, sizeof(param))) { pr_err("%s: CTU\n", __func__); return -EFAULT; } return 0; } break; case RFIC_IOCTL_SET_PDM: { struct pdm_param param; void __iomem *pdmaddr; u16 value; int num; if (copy_from_user(¶m, argp, sizeof(param))) { pr_err("%s: CFU\n", __func__); return -EFAULT; } if ((pdfi->ftrid != 0) || (param.num > 5)) { pr_err("%s: Invalid id or num\n", __func__); return -EINVAL; } mutex_lock(&pdev->lock); if (param.num > 2) num = param.num + 1; else num = param.num; value = (u16) param.value; pdmaddr = pdm_base + PDM_1_1_CTL * num; __raw_writel(param.enable, pdmaddr); if (param.enable) __raw_writel(value, pdmaddr + 4); mutex_unlock(&pdev->lock); return 0; } break; default: return -EINVAL; } return 0; }
static int ftr_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct ftr_dev_node_info *ptr; struct resource *mem_res; struct clk *pdm_clk; int ret; u8 version = 0; pr_debug("%s: me = %p, parent = %p\n", __func__, pdev, pdev->dev.parent); mutex_lock(&rficlock); if (n_dev >= RFIC_DEVICE_NUM) { pr_warn("%s: Invalid devices %d\n", __func__, n_dev); mutex_unlock(&rficlock); return -EINVAL; } if (!n_dev) { rfbid = rf_interface_id(); if ((rfbid != 0xff) && (rfbid != 0)) rfbid = rfbid & RF_TYPE_48; switch (rfbid) { case RF_TYPE_16: ftr_regulator_init(pdev); break; case RF_TYPE_32: glu_regulator_init(pdev); break; case RF_TYPE_48: mtr_regulator_init(pdev); break; default: pr_warn("%s:Regulators not turned ON %d\n", __func__, rfbid); } rfbid = rf_interface_id(); pr_info("%s: RF Board Id 0x%x\n", __func__, rfbid); mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); grfc_base = devm_ioremap_resource(&pdev->dev, mem_res); if (IS_ERR(grfc_base)) { mutex_unlock(&rficlock); return PTR_ERR(grfc_base); } mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); wf_base = devm_ioremap_resource(&pdev->dev, mem_res); if (IS_ERR(wf_base)) { mutex_unlock(&rficlock); return PTR_ERR(wf_base); } mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 2); pdm_base = devm_ioremap_resource(&pdev->dev, mem_res); if (IS_ERR(pdm_base)) { mutex_unlock(&rficlock); return PTR_ERR(pdm_base); } ret = device_create_file(&pdev->dev, &dev_attr_rfboard_id); WARN_ON(ret); pdm_clk = clk_get(&pdev->dev, "ahb_clk"); if (IS_ERR(pdm_clk)) { pdm_clk = NULL; pr_err("%s: AHB CLK is NULL\n", __func__); } else { pr_debug("%s: AHB CLK is 0x%x\n", __func__, (unsigned int)pdm_clk); clk_prepare(pdm_clk); clk_enable(pdm_clk); } pdm_clk = clk_get(&pdev->dev, "pdm2_clk"); if (IS_ERR(pdm_clk)) { pdm_clk = NULL; pr_err("%s: PDM2 CLK is NULL\n", __func__); } else { pr_debug("%s: PDM2 CLK is 0x%x\n", __func__, (unsigned int)pdm_clk); clk_prepare(pdm_clk); clk_enable(pdm_clk); } if ((rfbid > RF_TYPE_48) && (rfbid != 0xff)) { fsm9900_mtr_init(); pdm_mtr_enable(); pr_info("%s: MTR PDM Enabled\n", __func__); } else if ((rfbid > RF_TYPE_16) && (rfbid < RF_TYPE_32)) { fsm9900_rfic_init(); pdm_enable(); pr_info("%s: PDM Enabled\n", __func__); } else if ((rfbid > RF_TYPE_32) && (rfbid < RF_TYPE_48)) { fsm9900_gluon_init(); pr_info("%s: Gluon Enabled\n", __func__); } else { pr_warn("%s:PDMs not configured %d\n", __func__, rfbid); } } ptr = ftr_dev_info + n_dev; ptr->dev = &pdev->dev; if ((n_dev >= 1) && (n_dev <= 7)) { struct ssbi *ssbi = platform_get_drvdata(to_platform_device(pdev->dev.parent)); if ((rfbid > RF_TYPE_48) && (n_dev <= 4)) { ssbi->controller_type = FSM_SBI_CTRL_GENI_SSBI2_ARBITER; set_ssbi_mode_2(ssbi->base); pr_debug("%s: SSBI2 = 0x%x\n", __func__, ssbi->controller_type); rfic_pvc_enable(ssbi->base, 3); } else { ssbi->controller_type = FSM_SBI_CTRL_GENI_SSBI_ARBITER; set_ssbi_mode_1(ssbi->base); pr_debug("%s: SSBI1 = 0x%x\n", __func__, ssbi->controller_type); if ((n_dev == 1) || (n_dev == 2)) rfic_pvc_enable(ssbi->base, 1); if ((n_dev == 3) && (rfbid > RF_TYPE_16) && (rfbid < RF_TYPE_32)) rfic_pvc_enable(ssbi->base, 2); } platform_set_drvdata(to_platform_device(pdev->dev.parent), ssbi); } if ((rfbid > RF_TYPE_16) && (rfbid < RF_TYPE_48) && (n_dev == 1)) { ssbi_write(pdev->dev.parent, 0xff, &version, 1); ssbi_read(pdev->dev.parent, 0x2, &version, 1); pr_info("%s: FTR1 Version = %02x\n", __func__, version); ptr->grfcctrladdr = grfc_base + 0x10; /* grp 4 */ ptr->grfcmaskaddr = grfc_base + 0x30; __raw_writel(0x00001800, ptr->grfcmaskaddr); ptr->maskvalue = 0x00001800; ptr->busselect[TX1_BUS] = 0x00000000; ptr->busselect[TX2_BUS] = 0x00001000; ptr->busselect[MISC_BUS] = 0x00000800; ptr->busselect[RX_BUS] = 0x00001800; } else if ((rfbid > RF_TYPE_16) && (rfbid < RF_TYPE_48) && (n_dev == 2)) { ssbi_write(pdev->dev.parent, 0xff, &version, 1); ssbi_read(pdev->dev.parent, 0x2, &version, 1); pr_info("%s: FTR2 Version = %02x\n", __func__, version); ptr->grfcctrladdr = grfc_base + 0x14; /* grp 5*/ ptr->grfcmaskaddr = grfc_base + 0x34; __raw_writel(0x00000600, ptr->grfcmaskaddr); ptr->maskvalue = 0x00000600; ptr->busselect[TX1_BUS] = 0x000000; ptr->busselect[TX2_BUS] = 0x00000400; ptr->busselect[MISC_BUS] = 0x00000200; ptr->busselect[RX_BUS] = 0x00000600; } mutex_init(&ptr->lock); if (rfbid < RF_TYPE_48) { ret = misc_register(ftr_misc_dev + n_dev); if (ret < 0) { misc_deregister(ftr_misc_dev + n_dev); mutex_unlock(&rficlock); return ret; } } else { ret = misc_register(mtr_misc_dev + n_dev); if (ret < 0) { misc_deregister(mtr_misc_dev + n_dev); mutex_unlock(&rficlock); return ret; } } n_dev++; pr_debug("%s: num_of_ssbi_devices = %d\n", __func__, n_dev); mutex_unlock(&rficlock); return of_platform_populate(np, NULL, NULL, &pdev->dev); }
int pm8058_reset_pwr_off(int reset) { int rc; u8 pon; u8 ctrl; u8 smpl; if (pmic_chip == NULL) return -ENODEV; mutex_lock(&pmic_chip->pm_lock); /* Set regulator L22 to 1.225V in high power mode. */ rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_L22_CTRL, &ctrl, 1); if (rc) { pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__, SSBI_REG_ADDR_L22_CTRL, rc); goto get_out3; } /* Leave pull-down state intact. */ ctrl &= 0x40; ctrl |= 0x93; rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_L22_CTRL, &ctrl, 1); if (rc) pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n", __func__, SSBI_REG_ADDR_L22_CTRL, ctrl, rc); get_out3: if (!reset) { /* Only modify the SLEEP_CNTL reg if shutdown is desired. */ rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_SLEEP_CNTL, &smpl, 1); if (rc) { pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__, SSBI_REG_ADDR_SLEEP_CNTL, rc); goto get_out2; } smpl &= ~PM8058_SLEEP_SMPL_EN_MASK; smpl |= PM8058_SLEEP_SMPL_EN_PWR_OFF; rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_SLEEP_CNTL, &smpl, 1); if (rc) pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n", __func__, SSBI_REG_ADDR_SLEEP_CNTL, smpl, rc); } get_out2: rc = ssbi_read(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_1, &pon, 1); if (rc) { pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n", __func__, SSBI_REG_ADDR_PON_CNTL_1, rc); goto get_out; } pon &= ~PM8058_PON_WD_EN_MASK; pon |= reset ? PM8058_PON_WD_EN_RESET : PM8058_PON_WD_EN_PWR_OFF; rc = ssbi_write(pmic_chip->dev, SSBI_REG_ADDR_PON_CNTL_1, &pon, 1); if (rc) { pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n", __func__, SSBI_REG_ADDR_PON_CNTL_1, pon, rc); goto get_out; } get_out: mutex_unlock(&pmic_chip->pm_lock); return rc; }