static int ab8500_regulator_get_voltage(struct regulator_dev *rdev) { int ret, val; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); u8 regval; if (info == NULL) { dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; } ret = abx500_get_register_interruptible(info->dev, info->voltage_bank, info->voltage_reg, ®val); if (ret < 0) { dev_err(rdev_get_dev(rdev), "couldn't read voltage reg for regulator\n"); return ret; } dev_vdbg(rdev_get_dev(rdev), "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," " 0x%x\n", info->desc.name, info->voltage_bank, info->voltage_reg, info->voltage_mask, regval); /* vintcore has a different layout */ val = regval & info->voltage_mask; if (info->desc.id == AB8500_LDO_INTCORE) ret = info->voltages[val >> 0x3]; else
static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) { int ret; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); u8 regval; if (info == NULL) { dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; } ret = abx500_get_register_interruptible(info->dev, info->update_bank, info->update_reg, ®val); if (ret < 0) { dev_err(rdev_get_dev(rdev), "couldn't read 0x%x register\n", info->update_reg); return ret; } dev_vdbg(rdev_get_dev(rdev), "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," " 0x%x\n", info->desc.name, info->update_bank, info->update_reg, info->update_mask, regval); if (regval & info->update_mask) info->is_enabled = true; else info->is_enabled = false; return info->is_enabled; }
static int charging_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) { struct device *dev = (struct device *) data ; int i ; unsigned char c ; int len = 0; int ret ; for (i=0;i<ARRAY_SIZE(ab8500_power_registers);i++) { c=0xff ; ret = abx500_get_register_interruptible(dev, ab8500_power_registers[i].region, ab8500_power_registers[i].address, &c); if (ret>=0) { len+=sprintf(page+len,"(%#04x %#04x)%s = 0x%02x\n", ab8500_power_registers[i].region, ab8500_power_registers[i].address, ab8500_power_registers[i].name, c); msleep(10); } } *eof=-1; return len ; }
static int ab8500_ext_regulator_is_enabled(struct regulator_dev *rdev) { int ret; struct ab8500_ext_regulator_info *info = rdev_get_drvdata(rdev); u8 regval; if (info == NULL) { dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; } ret = abx500_get_register_interruptible(info->dev, info->update_bank, info->update_reg, ®val); if (ret < 0) { dev_err(rdev_get_dev(rdev), "couldn't read 0x%x register\n", info->update_reg); return ret; } dev_dbg(rdev_get_dev(rdev), "%s-is_enabled (bank, reg, mask, value):" " 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", info->desc.name, info->update_bank, info->update_reg, info->update_mask, regval); if (((regval & info->update_mask) == info->update_val_lp) || ((regval & info->update_mask) == info->update_val_hp)) return 1; else return 0; }
static void ab8500_turn_off_accdet_comparator(struct platform_device *pdev) { struct abx500_ad *dd = platform_get_drvdata(pdev); /* Turn off AccDetect comparators and pull-up */ (void) abx500_get_register_interruptible( &dd->pdev->dev, AB8500_ECI_AV_ACC, AB8500_ACC_DET_CTRL_REG, &acc_det_ctrl_suspend_val); (void) abx500_set_register_interruptible( &dd->pdev->dev, AB8500_ECI_AV_ACC, AB8500_ACC_DET_CTRL_REG, 0); }
/* * returns the high level status whether some accessory is connected (1|0). */ static int ab8500_detect_plugged_in(struct abx500_ad *dd) { u8 value = 0; int status = abx500_get_register_interruptible( &dd->pdev->dev, AB8500_INTERRUPT, AB8500_IT_SOURCE5_REG, &value); if (status < 0) { dev_err(&dd->pdev->dev, "%s: reg read failed (%d).\n", __func__, status); return 0; } if (dd->pdata->is_detection_inverted) return value & BIT_ITSOURCE5_ACCDET1 ? 1 : 0; else return value & BIT_ITSOURCE5_ACCDET1 ? 0 : 1; }
static u8 read_reg(u8 reg) { if (!ab3550_dev) { pr_err("%s: The AB3550 codec driver not initialized.\n", __func__); return 0; } if (reg < AB3550_FIRST_REG) return 0; else if (reg <= AB3550_LAST_REG) { u8 val; abx500_get_register_interruptible( ab3550_dev, I2C_BANK, reg, &val); return val; } else if (reg - AB3550_LAST_REG - 1 < ARRAY_SIZE(virtual_regs)) return virtual_regs[reg - AB3550_LAST_REG - 1]; dev_warn(ab3550_dev, "%s: out-of-scope reigster %u.\n", __func__, reg); return 0; }
static u8 read_reg(u8 reg) { if (!ab5500_dev) { pr_err("%s: The AB5500 codec driver not initialized.\n", __func__); return 0; } /* Check if the reg value falls within the range of AB5500 real * registers.If so, set the mask */ if (reg < AB5500_FIRST_REG) return 0; else if (reg <= AB5500_LAST_REG) { u8 val; abx500_get_register_interruptible( ab5500_dev, AB5500_BANK_AUDIO_HEADSETUSB, reg, &val); return val; } else if (reg - AB5500_LAST_REG - 1 < ARRAY_SIZE(virtual_regs)) return virtual_regs[reg - AB5500_LAST_REG - 1]; dev_warn(ab5500_dev, "%s: out-of-scope reigster %u.\n", __func__, reg); return 0; }
/** * musb_force_detect : detect the USB cable during boot time. * @mode: value for mode. * * This function is used to detect the USB cable during boot time. */ int musb_force_detect(u8 mode) { int ret; u8 usb_status = 0; u8 val = 0; if (!device) return -EINVAL; /* Disabling PHY before selective enable or disable */ abx500_set_register_interruptible(device, AB8500_USB, AB8500_USB_PHY_CTRL_REG, AB8500_USB_DEVICE_ENABLE); udelay(200); abx500_set_register_interruptible(device, AB8500_USB, AB8500_USB_PHY_CTRL_REG, AB8500_USB_DEVICE_DISABLE); abx500_set_register_interruptible(device, AB8500_USB, AB8500_USB_PHY_CTRL_REG, AB8500_USB_HOST_ENABLE); udelay(200); abx500_set_register_interruptible(device, AB8500_USB, AB8500_USB_PHY_CTRL_REG, AB8500_USB_HOST_DISABLE); if (mode == MUSB_HOST || mode == MUSB_OTG) { ret = abx500_get_register_interruptible(device, AB8500_INTERRUPT, AB8500_IT_SOURCE20_REG, &usb_status); if (ret < 0) { dev_err(device, "Read IT 20 failed\n"); return ret; } if (usb_status & AB8500_SRC_INT_USB_HOST) { boot_time_flag = USB_ENABLE; /* Change the current state */ stm_musb_curr_state = USB_HOST; usb_host_phy_en(USB_ENABLE); } } if (mode == MUSB_PERIPHERAL || mode == MUSB_OTG) { ret = abx500_get_register_interruptible(device, AB8500_INTERRUPT, AB8500_IT_SOURCE2_REG, &usb_status); if (ret < 0) { dev_err(device, "Read IT 2 failed\n"); return ret; } if (usb_status & AB8500_SRC_INT_USB_DEVICE) { /* Check if it is a dedicated charger */ (void)abx500_get_register_interruptible(device, AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); val = (val & AB8500_USB_LINK_STATUS) >> 3; if (val == USB_LINK_DEDICATED_CHG) { /* Change the current state */ stm_musb_curr_state = USB_DEDICATED_CHG; } else { boot_time_flag = USB_ENABLE; /* Change the current state */ stm_musb_curr_state = USB_DEVICE; usb_device_phy_en(USB_ENABLE); } }
/** * musb_phy_en : register USB callback handlers for ab8500 * @mode: value for mode. * * This function is used to register USB callback handlers for ab8500. */ int musb_phy_en(u8 mode) { int ret = -1; u8 save_val; if (!device) return -EINVAL; ab8500_rev = abx500_get_chip_id(device); if (ab8500_rev < 0) { dev_err(device, "get chip id failed\n"); return ab8500_rev; } if (!((ab8500_rev == AB8500_REV_20) || (ab8500_rev == AB8500_REV_30) || (ab8500_rev == AB8500_REV_33))) { dev_err(device, "Unknown AB type!\n"); return -ENODEV; } musb_vape_supply = regulator_get(device, "v-ape"); if (IS_ERR(musb_vape_supply)) { dev_err(device, "Could not get %s:v-ape supply\n", dev_name(device)); ret = PTR_ERR(musb_vape_supply); return ret; } musb_vintcore_supply = regulator_get(device, "v-intcore"); if (IS_ERR(musb_vintcore_supply)) { dev_err(device, "Could not get %s:v-intcore12 supply\n", dev_name(device)); ret = PTR_ERR(musb_vintcore_supply); return ret; } musb_smps2_supply = regulator_get(device, "musb_1v8"); if (IS_ERR(musb_smps2_supply)) { dev_err(device, "Could not get %s:v-intcore12 supply\n", dev_name(device)); ret = PTR_ERR(musb_smps2_supply); return ret; } sysclock = clk_get(device, "sysclk"); if (IS_ERR(sysclock)) { ret = PTR_ERR(sysclock); sysclock = NULL; return ret; } /* * When usb cable is not connected,set Qos for VAPE to 50. * This is done to run APE at low OPP when usb is not used. */ prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, DEVICE_NAME, 50); if (mode == MUSB_HOST || mode == MUSB_OTG) { ret = request_threaded_irq(irq_host_remove, NULL, usb_host_remove_handler, IRQF_NO_SUSPEND | IRQF_SHARED, "usb-host-remove", device); if (ret < 0) { printk(KERN_ERR "failed to set the callback" " handler for usb host" " removal\n"); return ret; } } if ((mode == MUSB_PERIPHERAL) || (mode == MUSB_OTG)) { ret = request_threaded_irq(irq_device_remove, NULL, usb_device_remove_handler, IRQF_NO_SUSPEND | IRQF_SHARED, "usb-device-remove", device); if (ret < 0) { printk(KERN_ERR "failed to set the callback" " handler for usb host" " removal\n"); return ret; } } /* create a thread for work */ usb_cable_wq = create_singlethread_workqueue( "usb_cable_wq"); if (usb_cable_wq == NULL) return -ENOMEM; ret = request_threaded_irq(irq_device_insert, NULL, usb_device_insert_handler, IRQF_NO_SUSPEND | IRQF_SHARED, "usb-device-insert", device); if (ret < 0) { printk(KERN_ERR "failed to set the callback" " handler for usb device" " insert\n"); return ret; } INIT_WORK(&usb_host_remove, usb_host_remove_work); INIT_WORK(&usb_device_remove, usb_device_remove_work); INIT_WORK(&usb_lnk_status_update, usb_link_status_update_work); if (ab8500_rev == AB8500_REV_20) INIT_WORK(&usb_dedicated_charger_remove, usb_dedicated_charger_remove_work); /* Required for Host, Device and OTG mode */ init_completion(&usb_link_status_update); ret = request_threaded_irq(irq_link_status_update, NULL, usb_link_status_update_handler, IRQF_NO_SUSPEND | IRQF_SHARED, "usb-link-status-update", device); if (ret < 0) { printk(KERN_ERR "failed to set the callback" " handler for usb charge" " detect done\n"); return ret; } #ifdef CONFIG_USB_OTG_20 ret = request_threaded_irq(irq_adp_plug, NULL, irq_adp_plug_handler, IRQF_SHARED, "usb-adp-plug", device); if (ret < 0) { printk(KERN_ERR "failed to set the callback" " handler for usb adp" " plug\n"); return ret; } ret = request_threaded_irq(irq_adp_unplug, NULL, irq_adp_unplug_handler, IRQF_SHARED, "usb-adp-unplug", device); if (ret < 0) { printk(KERN_ERR "failed to set the callback" " handler for usb adp" " unplug\n"); return ret; } #endif /* Write Phy tuning values */ if ((ab8500_rev == AB8500_REV_30) || (ab8500_rev == AB8500_REV_33)) { /* Enable the PBT/Bank 0x12 access * Save old bank settings for * later restore */ ret = abx500_get_register_interruptible(device, AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, &save_val); ret = abx500_set_register_interruptible(device, AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, 0x01); if (ret < 0) printk(KERN_ERR "Failed to enable bank12" " access ret=%d\n", ret); ret = abx500_set_register_interruptible(device, AB8500_DEBUG, AB8500_USB_PHY_TUNE1, 0xC8); if (ret < 0) printk(KERN_ERR "Failed to set PHY_TUNE1" " register ret=%d\n", ret); ret = abx500_set_register_interruptible(device, AB8500_DEBUG, AB8500_USB_PHY_TUNE2, 0x00); if (ret < 0) printk(KERN_ERR "Failed to set PHY_TUNE2" " register ret=%d\n", ret); ret = abx500_set_register_interruptible(device, AB8500_DEBUG, AB8500_USB_PHY_TUNE3, 0x78); if (ret < 0) printk(KERN_ERR "Failed to set PHY_TUNE3" " regester ret=%d\n", ret); /* Switch back to previous mode/disable Bank 0x12 access */ ret = abx500_set_register_interruptible(device, AB8500_DEVELOPMENT, AB8500_BANK12_ACCESS, save_val); if (ret < 0) printk(KERN_ERR "Failed to switch bank12" " access ret=%d\n", ret); } return 0; }
static void usb_charger_det_enable(struct work_struct *work) { int i, ret; u8 val; /* * Until the IT source register is read the UsbLineStatus * register is not updated. */ ret = abx500_get_register_interruptible(device, AB8500_INTERRUPT, AB8500_IT_SOURCE21_REG, &val); if (ret < 0) { dev_err(device, "%s ab8500 read 0x0e14 failed\n", __func__); return; } ret = abx500_get_register_interruptible(device, AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); if (ret < 0) { dev_err(device, "%s ab8500 read 0x580 failed\n", __func__); return; } if (val != 0) return; /* connection type already detected, so we do not need workaround */ dev_info(device, "USB cable detect workaround activated\n"); val = 0; ret = abx500_get_register_interruptible(device, AB8500_INTERRUPT, AB8500_IT_SOURCE2_REG, &val); if (ret < 0) { dev_err(device, "%s ab8500 read 0x0e01 failed\n", __func__); return; } if (!(val & 0x80)) return; /* workaround will not be activated because vbus is not detected */ ret = abx500_set_register_interruptible(device, AB8500_USB, AB8500_USB_PHY_CTRL_REG, 0x00); if (ret < 0) { dev_err(device, "%s ab8500 write 0x58A failed\n", __func__); return; } ret = abx500_set_register_interruptible(device, AB8500_USB, AB8500_USB_LINE_CTRL2_REG, 0x01); if (ret < 0) { dev_err(device, "%s ab8500 write 0x582 failed\n", __func__); return; } for (i = 10; i != 0; i--) { val = 0; ret = abx500_get_register_interruptible(device, AB8500_INTERRUPT, AB8500_IT_LATCH12_REG, &val); if (ret < 0) { dev_err(device, "%s ab8500 read 0x0e2b failed\n", __func__); return; } if (val & 0x80) break; msleep(2); } ret = abx500_set_register_interruptible(device, AB8500_USB, AB8500_USB_LINE_CTRL2_REG, 0x00); if (ret < 0) { dev_err(device, "%s ab8500 write 0x582 failed\n", __func__); return; } ret = abx500_get_register_interruptible(device, AB8500_USB, AB8500_USB_LINE_STAT_REG, &val); if (ret < 0) { dev_err(device, "%s ab8500 read 0x580 failed\n", __func__); return; } }