Esempio n. 1
0
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, &regval);
	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
Esempio n. 2
0
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, &regval);
	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;
}
Esempio n. 3
0
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, &regval);
	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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
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;
	}
}