/* Fill in pdata elements based on values found in device tree. */
static int qpnp_regulator_get_dt_config(struct spmi_device *spmi,
				struct qpnp_regulator_platform_data *pdata)
{
	struct resource *res;
	struct device_node *node = spmi->dev.of_node;
	int rc = 0;

	pdata->init_data.constraints.input_uV
		= pdata->init_data.constraints.max_uV;

	res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&spmi->dev, "%s: node is missing base address\n",
			__func__);
		return -EINVAL;
	}
	pdata->base_addr = res->start;

	/*
	 * Initialize configuration parameters to use hardware default in case
	 * no value is specified via device tree.
	 */
	pdata->auto_mode_enable		= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->bypass_mode_enable	= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->ocp_enable		= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->pull_down_enable		= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->soft_start_enable	= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->boost_current_limit	= QPNP_BOOST_CURRENT_LIMIT_HW_DEFAULT;
	pdata->pin_ctrl_enable	    = QPNP_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT;
	pdata->pin_ctrl_hpm	    = QPNP_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT;
	pdata->vs_soft_start_strength	= QPNP_VS_SOFT_START_STR_HW_DEFAULT;

	/* These bindings are optional, so it is okay if they are not found. */
	of_property_read_u32(node, "qcom,auto-mode-enable",
		&pdata->auto_mode_enable);
	of_property_read_u32(node, "qcom,bypass-mode-enable",
		&pdata->bypass_mode_enable);
	of_property_read_u32(node, "qcom,ocp-enable", &pdata->ocp_enable);
	of_property_read_u32(node, "qcom,pull-down-enable",
		&pdata->pull_down_enable);
	of_property_read_u32(node, "qcom,soft-start-enable",
		&pdata->soft_start_enable);
	of_property_read_u32(node, "qcom,boost-current-limit",
		&pdata->boost_current_limit);
	of_property_read_u32(node, "qcom,pin-ctrl-enable",
		&pdata->pin_ctrl_enable);
	of_property_read_u32(node, "qcom,pin-ctrl-hpm", &pdata->pin_ctrl_hpm);
	of_property_read_u32(node, "qcom,vs-soft-start-strength",
		&pdata->vs_soft_start_strength);
	of_property_read_u32(node, "qcom,system-load", &pdata->system_load);
	of_property_read_u32(node, "qcom,enable-time", &pdata->enable_time);
	of_property_read_u32(node, "qcom,ocp-enable-time",
		&pdata->ocp_enable_time);

	return rc;
}
static int qpnp_vibrator_probe(struct spmi_device *spmi)
{
	struct qpnp_vib *vib;
	struct resource *vib_resource;
	int rc;

	vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL);
	if (!vib)
		return -ENOMEM;

	vib->spmi = spmi;

	vib_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0);
	if (!vib_resource) {
		dev_err(&spmi->dev, "Unable to get vibrator base address\n");
		return -EINVAL;
	}
	vib->base = vib_resource->start;

	rc = qpnp_vib_parse_dt(vib);
	if (rc) {
		dev_err(&spmi->dev, "DT parsing failed\n");
		return rc;
	}

	rc = qpnp_vibrator_config(vib);
	if (rc) {
		dev_err(&spmi->dev, "vib config failed\n");
		return rc;
	}

	mutex_init(&vib->lock);
	INIT_WORK(&vib->work, qpnp_vib_update);

	hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_timer.function = qpnp_vib_timer_func;

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = qpnp_vib_get_time;
	vib->timed_dev.enable = qpnp_vib_enable;

	dev_set_drvdata(&spmi->dev, vib);

	rc = timed_output_dev_register(&vib->timed_dev);
	if (rc < 0)
		return rc;

	device_create_file(vib->timed_dev.dev, &dev_attr_vtg_level);

	return rc;
}
static int bcl_get_devicetree_data(struct spmi_device *spmi)
{
	int ret = 0, irq_num = 0, temp_val = 0;
	struct resource *resource = NULL;
	char *key = NULL;
	const __be32 *prop = NULL;
	struct device_node *dev_node = spmi->dev.of_node;

	/* Get SPMI peripheral address */
	resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!resource) {
		pr_err("No base address defined\n");
		return -EINVAL;
	}
	bcl_perph->slave_id = spmi->sid;
	prop = of_get_address_by_name(dev_node,
			"fg_user_adc", 0, 0);
	if (prop) {
		bcl_perph->base_addr = be32_to_cpu(*prop);
		pr_debug("fg_user_adc@%04x\n", bcl_perph->base_addr);
	} else {
		dev_err(&spmi->dev, "No fg_user_adc registers found\n");
		return -EINVAL;
	}

	prop = of_get_address_by_name(dev_node,
			"pon_spare", 0, 0);
	if (prop) {
		bcl_perph->pon_spare_addr = be32_to_cpu(*prop);
		pr_debug("pon_spare@%04x\n", bcl_perph->pon_spare_addr);
	}

	/* Register SPMI peripheral interrupt */
	irq_num = spmi_get_irq_byname(spmi, NULL,
			BCL_VBAT_INT_NAME);
	if (irq_num < 0) {
		pr_err("Invalid vbat IRQ\n");
		ret = -ENXIO;
		goto bcl_dev_exit;
	}
	bcl_perph->param[BCL_PARAM_VOLTAGE].irq_num = irq_num;
	irq_num = spmi_get_irq_byname(spmi, NULL,
			BCL_IBAT_INT_NAME);
	if (irq_num < 0) {
		pr_err("Invalid ibat IRQ\n");
		ret = -ENXIO;
		goto bcl_dev_exit;
	}
	bcl_perph->param[BCL_PARAM_CURRENT].irq_num = irq_num;

	/* Get VADC and IADC scaling factor */
	key = "qcom,vbat-scaling-factor";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_VOLTAGE].scaling_factor);
	key = "qcom,vbat-gain-numerator";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_VOLTAGE].gain_factor_num);
	key = "qcom,vbat-gain-denominator";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_VOLTAGE].gain_factor_den);
	key = "qcom,ibat-scaling-factor";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_CURRENT].scaling_factor);
	key = "qcom,ibat-offset-numerator";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_CURRENT].offset_factor_num);
	key = "qcom,ibat-offset-denominator";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_CURRENT].offset_factor_den);
	key = "qcom,ibat-gain-numerator";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_CURRENT].gain_factor_num);
	key = "qcom,ibat-gain-denominator";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_CURRENT].gain_factor_den);
	key = "qcom,vbat-polling-delay-ms";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_VOLTAGE].polling_delay_ms);
	key = "qcom,ibat-polling-delay-ms";
	READ_CONV_FACTOR(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_CURRENT].polling_delay_ms);
	key = "qcom,inhibit-derating-ua";
	READ_OPTIONAL_PROP(dev_node, key, temp_val, ret,
		bcl_perph->param[BCL_PARAM_CURRENT].inhibit_derating_ua);

bcl_dev_exit:
	return ret;
}
static int qpnp_haptic_probe(struct spmi_device *spmi)
{
	struct qpnp_hap *hap;
	struct resource *hap_resource;
	int rc, i;

	hap = devm_kzalloc(&spmi->dev, sizeof(*hap), GFP_KERNEL);
	if (!hap)
		return -ENOMEM;

	hap->spmi = spmi;

	hap_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0);
	if (!hap_resource) {
		dev_err(&spmi->dev, "Unable to get haptic base address\n");
		return -EINVAL;
	}
	hap->base = hap_resource->start;

	dev_set_drvdata(&spmi->dev, hap);

	rc = qpnp_hap_parse_dt(hap);
	if (rc) {
		dev_err(&spmi->dev, "DT parsing failed\n");
		return rc;
	}

	rc = qpnp_hap_config(hap);
	if (rc) {
		dev_err(&spmi->dev, "hap config failed\n");
		return rc;
	}

	mutex_init(&hap->lock);
	mutex_init(&hap->wf_lock);
	INIT_WORK(&hap->work, qpnp_hap_worker);

	hrtimer_init(&hap->hap_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hap->hap_timer.function = qpnp_hap_timer;

	hap->timed_dev.name = "vibrator";
	hap->timed_dev.get_time = qpnp_hap_get_time;
	hap->timed_dev.enable = qpnp_hap_td_enable;

	rc = timed_output_dev_register(&hap->timed_dev);
	if (rc < 0) {
		dev_err(&spmi->dev, "timed_output registration failed\n");
		goto timed_output_fail;
	}

	for (i = 0; i < ARRAY_SIZE(qpnp_hap_attrs); i++) {
		rc = sysfs_create_file(&hap->timed_dev.dev->kobj,
				&qpnp_hap_attrs[i].attr);
		if (rc < 0) {
			dev_err(&spmi->dev, "sysfs creation failed\n");
			goto sysfs_fail;
		}
	}

	return 0;

sysfs_fail:
	for (i--; i >= 0; i--)
		sysfs_remove_file(&hap->timed_dev.dev->kobj,
				&qpnp_hap_attrs[i].attr);
	timed_output_dev_unregister(&hap->timed_dev);
timed_output_fail:
	cancel_work_sync(&hap->work);
	hrtimer_cancel(&hap->hap_timer);
	mutex_destroy(&hap->lock);
	mutex_destroy(&hap->wf_lock);

	return rc;
}
static int qpnp_typec_probe(struct spmi_device *spmi)
{
	int rc;
	struct resource *resource;
	struct qpnp_typec_chip *chip;

	resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!resource) {
		pr_err("Unable to get spmi resource for TYPEC\n");
		return -EINVAL;
	}

	chip = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_typec_chip),
			GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

	chip->dev = &spmi->dev;
	chip->spmi = spmi;

	/* parse DT */
	rc = qpnp_typec_parse_dt(chip);
	if (rc) {
		pr_err("failed to parse DT rc=%d\n", rc);
		return rc;
	}

	chip->base = resource->start;
	dev_set_drvdata(&spmi->dev, chip);
	device_init_wakeup(&spmi->dev, 1);
	mutex_init(&chip->typec_lock);

	/* determine initial status */
	rc = qpnp_typec_determine_initial_status(chip);
	if (rc) {
		pr_err("failed to determine initial state rc=%d\n", rc);
		return rc;
	}

	chip->type_c_psy.name		= TYPEC_PSY_NAME;
	chip->type_c_psy.get_property	= qpnp_typec_get_property;
	chip->type_c_psy.properties	= qpnp_typec_properties;
	chip->type_c_psy.num_properties	= ARRAY_SIZE(qpnp_typec_properties);

	rc = power_supply_register(chip->dev, &chip->type_c_psy);
	if (rc < 0) {
		pr_err("Unable to register  type_c_psy rc=%d\n", rc);
		return rc;
	}

	/* All irqs */
	rc = qpnp_typec_request_irqs(chip);
	if (rc) {
		pr_err("failed to request irqs rc=%d\n", rc);
		return rc;
	}

	pr_info("TypeC successfully probed state=%d CC-line-state=%d\n",
			chip->typec_state, chip->cc_line_state);

	return 0;
}
Exemple #6
0
static int __devinit qpnp_pon_probe(struct spmi_device *spmi)
{
	struct qpnp_pon *pon;
	struct resource *pon_resource;
	struct device_node *itr = NULL;
	u32 delay = 0;
	int rc, sys_reset;
	struct device *sec_powerkey;
#ifdef CONFIG_SEC_PM
	struct device *sec_power;
#endif
    	int ret;
	pon = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_pon),
							GFP_KERNEL);
	if (!pon) {
		dev_err(&spmi->dev, "Can't allocate qpnp_pon\n");
		return -ENOMEM;
	}

	sys_reset = of_property_read_bool(spmi->dev.of_node,
						"qcom,system-reset");
	if (sys_reset && sys_reset_dev) {
		dev_err(&spmi->dev, "qcom,system-reset property can only be specified for one device on the system\n");
		return -EINVAL;
	} else if (sys_reset) {
		sys_reset_dev = pon;
	}

	pon->spmi = spmi;

	/* get the total number of pon configurations */
	while ((itr = of_get_next_child(spmi->dev.of_node, itr)))
		pon->num_pon_config++;

	if (!pon->num_pon_config) {
		/* No PON config., do not register the driver */
		dev_err(&spmi->dev, "No PON config. specified\n");
		return -EINVAL;
	}

	pon->pon_cfg = devm_kzalloc(&spmi->dev,
			sizeof(struct qpnp_pon_config) * pon->num_pon_config,
								GFP_KERNEL);

	pon_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!pon_resource) {
		dev_err(&spmi->dev, "Unable to get PON base address\n");
		return -ENXIO;
	}
	pon->base = pon_resource->start;

	rc = of_property_read_u32(pon->spmi->dev.of_node,
				"qcom,pon-dbc-delay", &delay);
	if (rc) {
		if (rc != -EINVAL) {
			dev_err(&spmi->dev, "Unable to read debounce delay\n");
			return rc;
		}
	} else {
		delay = (delay << QPNP_PON_DELAY_BIT_SHIFT) / USEC_PER_SEC;
		delay = ilog2(delay);
		rc = qpnp_pon_masked_write(pon, QPNP_PON_DBC_CTL(pon->base),
						QPNP_PON_DBC_DELAY_MASK, delay);
		if (rc) {
			dev_err(&spmi->dev, "Unable to set PON debounce\n");
			return rc;
		}
	}

	dev_set_drvdata(&spmi->dev, pon);

	INIT_DELAYED_WORK(&pon->bark_work, bark_work_func);

	/* register the PON configurations */
	rc = qpnp_pon_config_init(pon);
	if (rc) {
		dev_err(&spmi->dev,
			"Unable to intialize PON configurations\n");
		return rc;
	}

#ifdef CONFIG_CONTROL_S2_RESET
	if (0 == sec_debug_is_enabled())
		qpnp_control_s2_reset(0);
#endif

#ifdef CONFIG_SEC_PM
	qpnp_control_s3_reset_timer();
	
	sec_power = device_create(sec_class, NULL, 0, NULL, "sec_power");
	if (IS_ERR(sec_power))
		pr_err("Failed to create device(sec_power)!\n");
	ret = device_create_file(sec_power, &dev_attr_enable_hw_reset);
	if (ret) {
		pr_err("Failed to create device file in sysfs entries(%s)!\n",
			dev_attr_enable_hw_reset.attr.name);
	}
	dev_set_drvdata(sec_power, pon);
#endif

	sec_powerkey = device_create(sec_class, NULL, 0, NULL, "sec_powerkey");
	if (IS_ERR(sec_powerkey))
		pr_err("Failed to create device(sec_powerkey)!\n");
	ret = device_create_file(sec_powerkey, &dev_attr_sec_powerkey_pressed);
	if (ret) {
		pr_err("Failed to create device file in sysfs entries(%s)!\n",
			dev_attr_sec_powerkey_pressed.attr.name);
	}
	dev_set_drvdata(sec_powerkey, pon);

	return rc;
}
static int __devinit qpnp_vibrator_probe(struct spmi_device *spmi)
{
	struct qpnp_vib *vib;
	struct resource *vib_resource;
	int rc;
	u8 val;
	u32 temp_val;

	vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL);
	if (!vib)
		return -ENOMEM;

	vib->spmi = spmi;

	vib->timeout = QPNP_VIB_DEFAULT_TIMEOUT;
	rc = of_property_read_u32(spmi->dev.of_node,
			"qcom,vib-timeout-ms", &temp_val);
	if (!rc) {
		vib->timeout = temp_val;
	} else if (rc != EINVAL) {
		dev_err(&spmi->dev, "Unable to read vib timeout\n");
		return rc;
	}

	vib->vtg_level = QPNP_VIB_DEFAULT_VTG_LVL;
	rc = of_property_read_u32(spmi->dev.of_node,
			"qcom,vib-vtg-level-mV", &temp_val);
	if (!rc) {
		vib->vtg_level = temp_val;
	} else if (rc != -EINVAL) {
		dev_err(&spmi->dev, "Unable to read vtg level\n");
		return rc;
	}

	vib->vtg_level /= 100;

#ifdef CONFIG_VIBRATOR_PM8941_HAPTIC
	vib->vtg_haptic_level = QPNP_VIB_MAX_LEVEL;
#endif

	vib_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0);
	if (!vib_resource) {
		dev_err(&spmi->dev, "Unable to get vibrator base address\n");
		return -EINVAL;
	}
	vib->base = vib_resource->start;

	/* save the control registers values */
	rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base));
	if (rc < 0)
		return rc;
	vib->reg_vtg_ctl = val;

	rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base));
	if (rc < 0)
		return rc;
	vib->reg_en_ctl = val;

	mutex_init(&vib->lock);
	INIT_WORK(&vib->work, qpnp_vib_update);

	hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_timer.function = qpnp_vib_timer_func;

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = qpnp_vib_get_time;
	vib->timed_dev.enable = qpnp_vib_enable;
#ifdef CONFIG_VIBRATOR_PM8941_HAPTIC
	vib->timed_dev.set_vtLevel = qpnp_vib_set_level;
	vib->timed_dev.get_vtLevel = qpnp_vib_get_level;
#endif
	dev_set_drvdata(&spmi->dev, vib);

	rc = timed_output_dev_register(&vib->timed_dev);
	if (rc < 0)
		return rc;

	vib_dev = vib;

	return rc;
}
Exemple #8
0
static int __devinit qpnp_vibrator_probe(struct spmi_device *spmi)
{
	struct qpnp_vib *vib;
	const __be32 *temp_dt;
	struct resource *vib_resource;
	int rc;
	u8 val;

	vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL);
	if (!vib)
		return -ENOMEM;

	vib->spmi = spmi;

	temp_dt = of_get_property(spmi->dev.of_node,
			"qcom,qpnp-vib-timeout-ms", NULL);
	if (temp_dt)
		vib->timeout = be32_to_cpu(*temp_dt);
	else
		vib->timeout = QPNP_VIB_DEFAULT_TIMEOUT;

	temp_dt = of_get_property(spmi->dev.of_node,
			"qcom,qpnp-vib-vtg-level-mV", NULL);
	if (temp_dt)
		vib->vtg_level = be32_to_cpu(*temp_dt);
	else
		vib->vtg_level = QPNP_VIB_DEFAULT_VTG_LVL;

	vib->vtg_level /= 100;

	vib_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0);
	if (!vib_resource) {
		dev_err(&spmi->dev, "Unable to get vibrator base address\n");
		return -EINVAL;
	}
	vib->base = vib_resource->start;

	
	rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base));
	if (rc < 0)
		return rc;
	vib->reg_vtg_ctl = val;

	rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base));
	if (rc < 0)
		return rc;
	vib->reg_en_ctl = val;

	spin_lock_init(&vib->lock);
	INIT_WORK(&vib->work, qpnp_vib_update);

	hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_timer.function = qpnp_vib_timer_func;

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = qpnp_vib_get_time;
	vib->timed_dev.enable = qpnp_vib_enable;

	dev_set_drvdata(&spmi->dev, vib);

	rc = timed_output_dev_register(&vib->timed_dev);
	if (rc < 0)
		return rc;

#ifdef CONFIG_VIB_TRIGGERS
	vib->enabler.name = "qpnp-vibrator";
	vib->enabler.default_trigger = "vibrator";
	vib->enabler.enable = qpnp_vib_trigger_enable;
	vib->enabler.trigger_data = vib;
	vib_trigger_enabler_register(&vib->enabler);
#endif

	vib_dev = vib;

	return rc;
}
static int qpnp_regulator_get_dt_config(struct spmi_device *spmi,
				struct qpnp_regulator_platform_data *pdata)
{
	struct resource *res;
	struct device_node *node = spmi->dev.of_node;
	int rc = 0;

	pdata->init_data.constraints.input_uV
		= pdata->init_data.constraints.max_uV;

	res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&spmi->dev, "%s: node is missing base address\n",
			__func__);
		return -EINVAL;
	}
	pdata->base_addr = res->start;

	
	pdata->ocp_irq = spmi_get_irq_byname(spmi, NULL, "ocp");
	if (pdata->ocp_irq < 0)
		pdata->ocp_irq = 0;

	pdata->auto_mode_enable		= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->bypass_mode_enable	= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->ocp_enable		= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->pull_down_enable		= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->soft_start_enable	= QPNP_REGULATOR_USE_HW_DEFAULT;
	pdata->boost_current_limit	= QPNP_BOOST_CURRENT_LIMIT_HW_DEFAULT;
	pdata->pin_ctrl_enable	    = QPNP_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT;
	pdata->pin_ctrl_hpm	    = QPNP_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT;
	pdata->vs_soft_start_strength	= QPNP_VS_SOFT_START_STR_HW_DEFAULT;
	pdata->hpm_enable		= QPNP_REGULATOR_USE_HW_DEFAULT;

	
	of_property_read_u32(node, "qcom,auto-mode-enable",
		&pdata->auto_mode_enable);
	of_property_read_u32(node, "qcom,bypass-mode-enable",
		&pdata->bypass_mode_enable);
	of_property_read_u32(node, "qcom,ocp-enable", &pdata->ocp_enable);
	of_property_read_u32(node, "qcom,ocp-max-retries",
		&pdata->ocp_max_retries);
	of_property_read_u32(node, "qcom,ocp-retry-delay",
		&pdata->ocp_retry_delay_ms);
	of_property_read_u32(node, "qcom,pull-down-enable",
		&pdata->pull_down_enable);
	of_property_read_u32(node, "qcom,soft-start-enable",
		&pdata->soft_start_enable);
	of_property_read_u32(node, "qcom,boost-current-limit",
		&pdata->boost_current_limit);
	of_property_read_u32(node, "qcom,pin-ctrl-enable",
		&pdata->pin_ctrl_enable);
	of_property_read_u32(node, "qcom,pin-ctrl-hpm", &pdata->pin_ctrl_hpm);
	of_property_read_u32(node, "qcom,hpm-enable", &pdata->hpm_enable);
	of_property_read_u32(node, "qcom,vs-soft-start-strength",
		&pdata->vs_soft_start_strength);
	of_property_read_u32(node, "qcom,system-load", &pdata->system_load);
	of_property_read_u32(node, "qcom,enable-time", &pdata->enable_time);

	return rc;
}
static int qpnp_flash_led_probe(struct spmi_device *spmi)
{
    struct qpnp_flash_led *led;
    struct resource *flash_resource;
    struct device_node *node, *temp;
    int rc, i = 0, j, num_leds = 0;
    u32 val;

    node = spmi->dev.of_node;
    if (node == NULL) {
        dev_info(&spmi->dev, "No flash device defined\n");
        return -ENODEV;
    }

    flash_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0);
    if (!flash_resource) {
        dev_err(&spmi->dev, "Unable to get flash LED base address\n");
        return -EINVAL;
    }

    led = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_flash_led),
                       GFP_KERNEL);
    if (!led) {
        dev_err(&spmi->dev,
                "Unable to allocate memory for flash LED\n");
        return -ENOMEM;
    }

    led->base = flash_resource->start;
    led->spmi_dev = spmi;

    led->pdata = devm_kzalloc(&spmi->dev,
                              sizeof(struct flash_led_platform_data), GFP_KERNEL);
    if (!led->pdata) {
        dev_err(&spmi->dev,
                "Unable to allocate memory for platform data\n");
        return -ENOMEM;
    }

    led->peripheral_type =
        (u8)qpnp_flash_led_get_peripheral_type(led);
    if (led->peripheral_type < 0) {
        dev_err(&spmi->dev, "Failed to get peripheral type\n");
        return rc;
    }

    rc = qpnp_flash_led_parse_common_dt(led, node);
    if (rc) {
        dev_err(&spmi->dev,
                "Failed to get common config for flash LEDs\n");
        return rc;
    }

    rc = qpnp_flash_led_init_settings(led);
    if (rc) {
        dev_err(&spmi->dev, "Failed to initialize flash LED\n");
        return rc;
    }

    temp = NULL;
    while ((temp = of_get_next_child(node, temp)))
        num_leds++;

    if (!num_leds)
        return -ECHILD;

    led->flash_node = devm_kzalloc(&spmi->dev,
                                   (sizeof(struct flash_node_data) * num_leds),
                                   GFP_KERNEL);
    if (!led->flash_node) {
        dev_err(&spmi->dev, "Unable to allocate memory\n");
        return -ENOMEM;
    }

    mutex_init(&led->flash_led_lock);

    for_each_child_of_node(node, temp) {
        led->flash_node[i].cdev.brightness_set =
            qpnp_flash_led_brightness_set;
        led->flash_node[i].cdev.brightness_get =
            qpnp_flash_led_brightness_get;
        led->flash_node[i].spmi_dev = spmi;

        INIT_WORK(&led->flash_node[i].work, qpnp_flash_led_work);
        rc = of_property_read_string(temp, "qcom,led-name",
                                     &led->flash_node[i].cdev.name);
        if (rc < 0) {
            dev_err(&led->spmi_dev->dev,
                    "Unable to read flash name\n");
            return rc;
        }

        rc = of_property_read_string(temp, "qcom,default-led-trigger",
                                     &led->flash_node[i].cdev.default_trigger);
        if (rc < 0) {
            dev_err(&led->spmi_dev->dev,
                    "Unable to read trigger name\n");
            return rc;
        }

        rc = of_property_read_u32(temp, "qcom,max-current", &val);
        if (!rc) {
            if (val < FLASH_LED_MIN_CURRENT_MA)
                val = FLASH_LED_MIN_CURRENT_MA;
            led->flash_node[i].max_current = (u16)val;
            led->flash_node[i].cdev.max_brightness = val;
        } else if (rc < 0) {
            dev_err(&led->spmi_dev->dev,
                    "Unable to read max current\n");
            return rc;
        }

        rc = led_classdev_register(&spmi->dev,
                                   &led->flash_node[i].cdev);
        if (rc) {
            dev_err(&spmi->dev, "Unable to register led\n");
            goto error_led_register;
        }

        led->flash_node[i].cdev.dev->of_node = temp;

        rc = qpnp_flash_led_parse_each_led_dt(led, &led->flash_node[i]);
        if (rc) {
            dev_err(&spmi->dev,
                    "Failed to parse config for each LED\n");
            goto error_led_register;
        }

        for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++) {
            rc =
                sysfs_create_file(&led->flash_node[i].cdev.dev->kobj,
                                  &qpnp_flash_led_attrs[j].attr);
            if (rc)
                goto error_led_register;
        }

        i++;
    }
static int __devinit qpnp_tm_probe(struct spmi_device *spmi)
{
	struct device_node *node;
	struct resource *res;
	struct qpnp_tm_chip *chip;
	struct thermal_zone_device_ops *tz_ops;
	char *tm_name;
	u32 default_temperature;
	int rc = 0;
	u8 raw_type[2], type, subtype;
#ifdef CONFIG_LGE_PM
	struct spmi_resource *spmi_resource;
	u8 batt_pres_rt_sts;
#endif
	if (!spmi || !(&spmi->dev) || !spmi->dev.of_node) {
		dev_err(&spmi->dev, "%s: device tree node not found\n",
			__func__);
		return -EINVAL;
	}

	node = spmi->dev.of_node;

	chip = kzalloc(sizeof(struct qpnp_tm_chip), GFP_KERNEL);
	if (!chip) {
		dev_err(&spmi->dev, "%s: Can't allocate qpnp_tm_chip\n",
			__func__);
		return -ENOMEM;
	}

	dev_set_drvdata(&spmi->dev, chip);

	res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&spmi->dev, "%s: node is missing base address\n",
			__func__);
		rc = -EINVAL;
		goto free_chip;
	}
	chip->base_addr	= res->start;
	chip->spmi_dev	= spmi;

	chip->irq = spmi_get_irq(spmi, NULL, 0);
	if (chip->irq < 0) {
		rc = chip->irq;
		dev_err(&spmi->dev, "%s: node is missing irq, rc=%d\n",
			__func__, rc);
		goto free_chip;
	}

	chip->tm_name = of_get_property(node, "label", NULL);
	if (chip->tm_name == NULL) {
		dev_err(&spmi->dev, "%s: node is missing label\n",
			__func__);
		rc = -EINVAL;
		goto free_chip;
	}

	tm_name = kstrdup(chip->tm_name, GFP_KERNEL);
	if (tm_name == NULL) {
		dev_err(&spmi->dev, "%s: could not allocate memory for label\n",
			__func__);
		rc = -ENOMEM;
		goto free_chip;
	}
	chip->tm_name = tm_name;

	INIT_DELAYED_WORK(&chip->irq_work, qpnp_tm_work);

	/* These bindings are optional, so it is okay if they are not found. */
	chip->thresh = THRESH_MAX + 1;
	rc = of_property_read_u32(node, "qcom,threshold-set", &chip->thresh);
	if (!rc && (chip->thresh < THRESH_MIN || chip->thresh > THRESH_MAX))
		dev_err(&spmi->dev, "%s: invalid qcom,threshold-set=%u specified\n",
			__func__, chip->thresh);

	chip->adc_type = QPNP_TM_ADC_NONE;
	rc = of_property_read_u32(node, "qcom,channel-num", &chip->adc_channel);
	if (!rc) {
		if (chip->adc_channel < 0 || chip->adc_channel >= ADC_MAX_NUM) {
			dev_err(&spmi->dev, "%s: invalid qcom,channel-num=%d specified\n",
				__func__, chip->adc_channel);
		} else {
			chip->adc_type = QPNP_TM_ADC_QPNP_ADC;
			chip->vadc_dev = qpnp_get_vadc(&spmi->dev,
							"temp_alarm");
			if (IS_ERR(chip->vadc_dev)) {
				rc = PTR_ERR(chip->vadc_dev);
				if (rc != -EPROBE_DEFER)
					pr_err("vadc property missing\n");
				goto err_cancel_work;
			}
		}
	}

	if (chip->adc_type == QPNP_TM_ADC_QPNP_ADC)
		tz_ops = &qpnp_thermal_zone_ops_qpnp_adc;
	else
		tz_ops = &qpnp_thermal_zone_ops_no_adc;

	chip->allow_software_override
		= of_property_read_bool(node, "qcom,allow-override");

	default_temperature = DEFAULT_NO_ADC_TEMP;
	rc = of_property_read_u32(node, "qcom,default-temp",
					&default_temperature);
	chip->temperature = default_temperature;

	rc = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, raw_type, 2);
	if (rc) {
		dev_err(&spmi->dev, "%s: could not read type register, rc=%d\n",
			__func__, rc);
		goto err_cancel_work;
	}
	type = raw_type[0];
	subtype = raw_type[1];

	if (type != QPNP_TM_TYPE || subtype != QPNP_TM_SUBTYPE) {
		dev_err(&spmi->dev, "%s: invalid type=%02X or subtype=%02X register value\n",
			__func__, type, subtype);
		rc = -ENODEV;
		goto err_cancel_work;
	}

	rc = qpnp_tm_init_reg(chip);
	if (rc) {
		dev_err(&spmi->dev, "%s: qpnp_tm_init_reg() failed, rc=%d\n",
			__func__, rc);
		goto err_cancel_work;
	}

	if (chip->adc_type == QPNP_TM_ADC_NONE) {
		rc = qpnp_tm_init_temp_no_adc(chip);
		if (rc) {
			dev_err(&spmi->dev, "%s: qpnp_tm_init_temp_no_adc() failed, rc=%d\n",
				__func__, rc);
			goto err_cancel_work;
		}
	}

	/* Start in HW control; switch to SW control when user changes mode. */
	chip->mode = THERMAL_DEVICE_DISABLED;
	rc = qpnp_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
	if (rc) {
		dev_err(&spmi->dev, "%s: qpnp_tm_shutdown_override() failed, rc=%d\n",
			__func__, rc);
		goto err_cancel_work;
	}

	chip->tz_dev = thermal_zone_device_register(tm_name, TRIP_NUM, chip,
			tz_ops, 0, 0, 0, 0);
	if (chip->tz_dev == NULL) {
		dev_err(&spmi->dev, "%s: thermal_zone_device_register() failed.\n",
			__func__);
		rc = -ENODEV;
		goto err_cancel_work;
	}

	rc = request_irq(chip->irq, qpnp_tm_isr, IRQF_TRIGGER_RISING, tm_name,
			chip);
	if (rc < 0) {
		dev_err(&spmi->dev, "%s: request_irq(%d) failed: %d\n",
			__func__, chip->irq, rc);
		goto err_free_tz;
	}

#ifdef CONFIG_LGE_PM
	spmi_for_each_container_dev(spmi_resource, spmi) {
		if (!spmi_resource) {
			pr_err("qpnp temp alarm : spmi resource absent\n");
			goto fail_bat_if;
		}

		res = spmi_get_resource(spmi, spmi_resource,
						IORESOURCE_MEM, 0);
		if (!(res && res->start)) {
			pr_err("node %s IO resource absent!\n",
				spmi->dev.of_node->full_name);
			goto fail_bat_if;
		}

		rc = qpnp_register_read(chip, &subtype,
				res->start + REG_OFFSET_PERP_SUBTYPE, 1);
		if (rc) {
			pr_err("Peripheral subtype read failed rc=%d\n", rc);
			goto fail_bat_if;
		}

		switch (subtype) {
		case SMBB_BAT_IF_SUBTYPE:
			pr_err("qpnp bat_if block enable for batt insert remove irq.\n");
			chip->bat_if_base = res->start;
			chip->batt_present_irq = spmi_get_irq_byname(chip->spmi_dev,
					spmi_resource, "batt-pres");

			if (chip->batt_present_irq < 0) {
				pr_err("Unable to get batt_present_irq\n");
				goto fail_bat_if;
			}

			rc = devm_request_irq(&(chip->spmi_dev->dev),
				chip->batt_present_irq,
				qpnp_batif_batt_inserted_removed_irq_handler,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"batt_remove_insert", chip);

			if (rc < 0) {
				pr_err("Can't request %d batt irq for insert, remove : %d\n",
						chip->batt_present_irq, rc);
				goto fail_bat_if;
			}

			rc = qpnp_register_masked_write(chip,
				INT_EN_SET(chip->bat_if_base),
				BATT_PRES_EN_BIT, BATT_PRES_EN_BIT, 1);

			if (rc) {
				pr_err("failed to enable BAT_IF_INT_EN_SET rc=%d\n", rc);
				goto fail_bat_if;
			}

			/* smb349 charger battery present W/A */
			rc = qpnp_register_read(chip, &batt_pres_rt_sts,
					INT_RT_STS(chip->bat_if_base), 1);
			if (rc) {
				pr_err("spmi read failed: addr=%03X, rc=%d\n",
						INT_RT_STS(chip->bat_if_base), rc);
				pr_err("assume that battery is present\n");

				/* battery present */
				pm_batt_rt_sts = 1;
			} else {
				pm_batt_rt_sts =
					(int)(batt_pres_rt_sts & BATT_IF_PRES_RT_STATUS);
				pr_err("%s : init PMIC battery RTS = %d\n",
						__func__, pm_batt_rt_sts);
			}

			enable_irq_wake(chip->batt_present_irq);
			break;
		default:
			break;
		}
	}

	INIT_WORK(&chip->batt_insert_remove_worker, batt_insert_remove_work);
	INIT_DELAYED_WORK(&chip->batt_insert_remove_worker_second,
				batt_insert_remove_work_second);
	wake_lock_init(&chip->battgone_wake_lock,
				WAKE_LOCK_SUSPEND, "batt removed");
#endif
	return 0;

err_free_tz:
	thermal_zone_device_unregister(chip->tz_dev);
err_cancel_work:
	cancel_delayed_work_sync(&chip->irq_work);
	kfree(chip->tm_name);
free_chip:
	dev_set_drvdata(&spmi->dev, NULL);
	kfree(chip);
	return rc;
#ifdef CONFIG_LGE_PM
fail_bat_if:
	pr_err("Cannot enable qpnp bat_if block.\n");
	return 0;
#endif
}
static int qpnp_vibrator_probe(struct spmi_device *spmi)
{
	struct qpnp_vib *vib;
	struct resource *vib_resource;
	int rc;

	printk(KERN_INFO "[VIB] %s\n", __func__);
	vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL);
	if (!vib)
		return -ENOMEM;

	vib->spmi = spmi;

	vib_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0);
	if (!vib_resource) {
		dev_err(&spmi->dev, "Unable to get vibrator base address\n");
		return -EINVAL;
	}
	vib->base = vib_resource->start;

	rc = qpnp_vib_parse_dt(vib);
	if (rc) {
		dev_err(&spmi->dev, "DT parsing failed\n");
		return rc;
	}

	rc = qpnp_vibrator_config(vib);
	if (rc) {
		dev_err(&spmi->dev, "vib config failed\n");
		return rc;
	}

	mutex_init(&vib->lock);
	INIT_WORK(&vib->work, qpnp_vib_update);

	hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_timer.function = qpnp_vib_timer_func;

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = qpnp_vib_get_time;
	vib->timed_dev.enable = qpnp_vib_enable;

	dev_set_drvdata(&spmi->dev, vib);

	rc = timed_output_dev_register(&vib->timed_dev);
	if (rc < 0)
		return rc;

	rc = device_create_file(vib->timed_dev.dev, &dev_attr_voltage_level);
	if (rc < 0) {
		printk(KERN_INFO "[VIB] %s, create sysfs fail: voltage_level\n", __func__);
	}

#ifdef CONFIG_VIB_TRIGGERS
		vib->enabler.name = "qpnp-vibrator";
		vib->enabler.default_trigger = "vibrator";
		vib->enabler.enable = qpnp_vib_trigger_enable;
		vib->enabler.trigger_data = vib;
		vib_trigger_enabler_register(&vib->enabler);
#endif

	return rc;
}
static int __devinit spm_regulator_probe(struct spmi_device *spmi)
{
	struct device_node *node = spmi->dev.of_node;
	struct regulator_init_data *init_data;
	struct spm_vreg *vreg;
	struct resource *res;
	int rc;

	if (!node) {
		dev_err(&spmi->dev, "%s: device node missing\n", __func__);
		return -ENODEV;
	}

	vreg = devm_kzalloc(&spmi->dev, sizeof(*vreg), GFP_KERNEL);
	if (!vreg) {
		pr_err("allocation failed.\n");
		return -ENOMEM;
	}
	vreg->spmi_dev = spmi;

	res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&spmi->dev, "%s: node is missing base address\n",
			__func__);
		return -EINVAL;
	}
	vreg->spmi_base_addr = res->start;

	rc = qpnp_fts2_check_type(vreg);
	if (rc)
		return rc;

	/*
                                                                       
                                                                 
                
  */
	rc = qpnp_fts2_init_range(vreg);
	if (rc)
		return rc;

	rc = qpnp_fts2_init_voltage(vreg);
	if (rc)
		return rc;

	rc = qpnp_fts2_init_mode(vreg);
	if (rc)
		return rc;

	rc = qpnp_fts2_init_step_rate(vreg);
	if (rc)
		return rc;

	init_data = of_get_regulator_init_data(&spmi->dev, node);
	if (!init_data) {
		dev_err(&spmi->dev, "%s: unable to allocate memory\n",
				__func__);
		return -ENOMEM;
	}
	init_data->constraints.input_uV = init_data->constraints.max_uV;
	init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS
						| REGULATOR_CHANGE_VOLTAGE;

	if (!init_data->constraints.name) {
		dev_err(&spmi->dev, "%s: node is missing regulator name\n",
			__func__);
		return -EINVAL;
	}

	vreg->rdesc.name	= init_data->constraints.name;
	vreg->rdesc.type	= REGULATOR_VOLTAGE;
	vreg->rdesc.owner	= THIS_MODULE;
	vreg->rdesc.ops		= &spm_regulator_ops;
	vreg->rdesc.n_voltages
		= (vreg->range->max_uV - vreg->range->set_point_min_uV)
			/ vreg->range->step_uV + 1;

	vreg->rdev = regulator_register(&vreg->rdesc, &spmi->dev,
					init_data, vreg, node);
	if (IS_ERR(vreg->rdev)) {
		rc = PTR_ERR(vreg->rdev);
		dev_err(&spmi->dev, "%s: regulator_register failed, rc=%d\n",
			__func__, rc);
		return rc;
	}

	dev_set_drvdata(&spmi->dev, vreg);

	pr_info("name=%s, range=%s, voltage=%d uV, mode=%s, step rate=%d uV/us\n",
		vreg->rdesc.name, vreg->range == &fts2_range0 ? "LV" : "MV",
		vreg->uV,
		vreg->init_mode & QPNP_FTS2_MODE_PWM ? "PWM" :
		    (vreg->init_mode & QPNP_FTS2_MODE_AUTO ? "AUTO" : "PFM"),
		vreg->step_rate);

	return rc;
}
static int __devinit pm8941_flash_probe(struct spmi_device *spmi)
{
	struct pm8941_flash_data *data;
	struct resource *flash_resource;
	struct device_node *node;
	int rc;
	const char *flash_label;

	node = spmi->dev.of_node;
	if (node == NULL)
		return -ENODEV;

	data = kzalloc(sizeof(struct pm8941_flash_data), GFP_KERNEL);
	if (!data) {
		dev_err(&spmi->dev, "Unable to allocate memory\n");
		return -ENOMEM;
	}

	data->cdev.minor = MISC_DYNAMIC_MINOR;
	data->cdev.name = "pm8941-flash";
	data->cdev.parent = &spmi->dev;
	data->spmi_dev = spmi;

	flash_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!flash_resource) {
		dev_err(&spmi->dev, "Unable to get flash base address\n");
		rc = -ENXIO;
		goto fail_id_check;
	}
	data->base = flash_resource->start;

	rc = of_property_read_string(node, "label", &flash_label);
	if (rc < 0) {
		dev_err(&spmi->dev, "Failure reading label, rc = %d\n", rc);
		goto fail_id_check;
	}

	if (strncmp(flash_label, "flash", sizeof("flash")) != 0) {
		dev_err(&spmi->dev, "No matching label\n");
		rc = -EINVAL;
		goto fail_id_check;
	}

	rc = pm8941_get_config_flash(data, node);
	if (rc < 0) {
		dev_err(&spmi->dev, "Unable to read config data\n");
		goto fail_id_check;
	}
	rc = pm8941_power_init(data);
	if (rc)
		goto fail_id_check;

	mutex_init(&data->lock);
	data->scheduled = false;
	data->boost_for_torch.requested = false;
	data->boost_for_flash.requested = false;

	rc =  pm8941_flash_initialize(data);
	if (rc < 0)
		goto fail_id_check;

	rc = pm8941_attributes_init(data);
	if (rc)
		goto remove_attributes;

	dev_set_drvdata(&spmi->dev, data);

	if (misc_register(&data->cdev)) {
		dev_err(&spmi->dev, "misc_register failed.\n");
		goto remove_attributes;
	}

	return 0;

remove_attributes:
	pm8941_attributes_remove(data);
fail_id_check:
	pm8941_regulator_exit(&data->spmi_dev->dev, &data->boost_for_flash);
	pm8941_regulator_exit(&data->spmi_dev->dev, &data->boost_for_torch);
	kfree(data);
	return rc;
}
static int __devinit qpnp_vibrator_probe(struct spmi_device *spmi)
{
	struct qpnp_vib *vib;
	const __be32 *temp_dt;
	struct resource *vib_resource;
	int rc = -ENOMEM;
	u8 val;

	vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL);
	if (!vib)
		goto gen_err;

	vib->spmi = spmi;

	temp_dt = of_get_property(spmi->dev.of_node,
			"qcom,qpnp-vib-timeout-ms", NULL);
	if (temp_dt)
		vib->timeout = be32_to_cpu(*temp_dt);
	else
		vib->timeout = QPNP_VIB_DEFAULT_TIMEOUT;

	temp_dt = of_get_property(spmi->dev.of_node,
			"qcom,qpnp-vib-vtg-level-mV", NULL);
	if (temp_dt)
		vib->vtg_level = be32_to_cpu(*temp_dt);
	else
		vib->vtg_level = QPNP_VIB_DEFAULT_VTG_LVL;

	vib->vtg_level /= QPNP_VIB_UV_PER_MV;

	vib_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0);
	if (!vib_resource) {
		dev_err(&spmi->dev, "Unable to get vibrator base address\n");
		rc = -EINVAL;
		goto gen_err;
	}
	vib->base = vib_resource->start;

	/* save the control registers values */
	rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base));
	if (rc < 0)
		goto gen_err;
	vib->reg_vtg_ctl = val;

	rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base));
	if (rc < 0)
		goto gen_err;
	vib->reg_en_ctl = val;

	spin_lock_init(&vib->lock);
	INIT_WORK(&vib->work, qpnp_vib_update);

	hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_timer.function = qpnp_vib_timer_func;

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = qpnp_vib_get_time;
	vib->timed_dev.enable = qpnp_vib_enable;

	rc = timed_output_dev_register(&vib->timed_dev);
	if (rc < 0)
		goto gen_err;

	vib->sysfs_dev.init_name = "qpnp_vib";

	rc = device_register(&vib->sysfs_dev);
	if (rc < 0) {
		dev_err(&spmi->dev, "%s: device_register failed %d\n",
			__func__, rc);
		goto error_dev_register;
	}
	rc = device_create_file(&vib->sysfs_dev, &qpnp_vib_attr);
	if (rc < 0) {
		dev_err(&spmi->dev, "%s: device_create_file failed %d\n",
			__func__, rc);
		goto error_device_create_file;
	}

	dev_set_drvdata(&spmi->dev, vib);

	vib_dev = vib;

	return rc;

error_device_create_file:
	device_unregister(&vib->sysfs_dev);
error_dev_register:
	timed_output_dev_unregister(&vib->timed_dev);
gen_err:
	return rc;
}
static int __devinit qpnp_tm_probe(struct spmi_device *spmi)
{
	struct device_node *node;
	struct resource *res;
	struct qpnp_tm_chip *chip;
	struct thermal_zone_device_ops *tz_ops;
	char *tm_name;
	u32 default_temperature;
	int rc = 0;
	u8 raw_type[2], type, subtype;

	if (!spmi || !(&spmi->dev) || !spmi->dev.of_node) {
		dev_err(&spmi->dev, "%s: device tree node not found\n",
			__func__);
		return -EINVAL;
	}

	node = spmi->dev.of_node;

	chip = kzalloc(sizeof(struct qpnp_tm_chip), GFP_KERNEL);
	if (!chip) {
		dev_err(&spmi->dev, "%s: Can't allocate qpnp_tm_chip\n",
			__func__);
		return -ENOMEM;
	}

	dev_set_drvdata(&spmi->dev, chip);

	res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&spmi->dev, "%s: node is missing base address\n",
			__func__);
		rc = -EINVAL;
		goto free_chip;
	}
	chip->base_addr	= res->start;
	chip->spmi_dev	= spmi;

	chip->irq = spmi_get_irq(spmi, NULL, 0);
	if (chip->irq < 0) {
		rc = chip->irq;
		dev_err(&spmi->dev, "%s: node is missing irq, rc=%d\n",
			__func__, rc);
		goto free_chip;
	}

	chip->tm_name = of_get_property(node, "label", NULL);
	if (chip->tm_name == NULL) {
		dev_err(&spmi->dev, "%s: node is missing label\n",
			__func__);
		rc = -EINVAL;
		goto free_chip;
	}

	tm_name = kstrdup(chip->tm_name, GFP_KERNEL);
	if (tm_name == NULL) {
		dev_err(&spmi->dev, "%s: could not allocate memory for label\n",
			__func__);
		rc = -ENOMEM;
		goto free_chip;
	}
	chip->tm_name = tm_name;

	INIT_DELAYED_WORK(&chip->irq_work, qpnp_tm_work);

	/* These bindings are optional, so it is okay if they are not found. */
	chip->thresh = THRESH_MAX + 1;
	rc = of_property_read_u32(node, "qcom,threshold-set", &chip->thresh);
	if (!rc && (chip->thresh < THRESH_MIN || chip->thresh > THRESH_MAX))
		dev_err(&spmi->dev, "%s: invalid qcom,threshold-set=%u specified\n",
			__func__, chip->thresh);

	chip->adc_type = QPNP_TM_ADC_NONE;
	rc = of_property_read_u32(node, "qcom,channel-num", &chip->adc_channel);
	if (!rc) {
		if (chip->adc_channel < 0 || chip->adc_channel >= ADC_MAX_NUM) {
			dev_err(&spmi->dev, "%s: invalid qcom,channel-num=%d specified\n",
				__func__, chip->adc_channel);
		} else {
			chip->adc_type = QPNP_TM_ADC_QPNP_ADC;
			rc = qpnp_vadc_is_ready();
			if (rc) {
				/* Probe retry, do not print an error message */
				goto err_cancel_work;
			}
		}
	}

	if (chip->adc_type == QPNP_TM_ADC_QPNP_ADC)
		tz_ops = &qpnp_thermal_zone_ops_qpnp_adc;
	else
		tz_ops = &qpnp_thermal_zone_ops_no_adc;

	chip->allow_software_override
		= of_property_read_bool(node, "qcom,allow-override");

	default_temperature = DEFAULT_NO_ADC_TEMP;
	rc = of_property_read_u32(node, "qcom,default-temp",
					&default_temperature);
	chip->temperature = default_temperature;

	rc = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, raw_type, 2);
	if (rc) {
		dev_err(&spmi->dev, "%s: could not read type register, rc=%d\n",
			__func__, rc);
		goto err_cancel_work;
	}
	type = raw_type[0];
	subtype = raw_type[1];

	if (type != QPNP_TM_TYPE || subtype != QPNP_TM_SUBTYPE) {
		dev_err(&spmi->dev, "%s: invalid type=%02X or subtype=%02X register value\n",
			__func__, type, subtype);
		rc = -ENODEV;
		goto err_cancel_work;
	}

	rc = qpnp_tm_init_reg(chip);
	if (rc) {
		dev_err(&spmi->dev, "%s: qpnp_tm_init_reg() failed, rc=%d\n",
			__func__, rc);
		goto err_cancel_work;
	}

	if (chip->adc_type == QPNP_TM_ADC_NONE) {
		rc = qpnp_tm_init_temp_no_adc(chip);
		if (rc) {
			dev_err(&spmi->dev, "%s: qpnp_tm_init_temp_no_adc() failed, rc=%d\n",
				__func__, rc);
			goto err_cancel_work;
		}
	}

	/* Start in HW control; switch to SW control when user changes mode. */
	chip->mode = THERMAL_DEVICE_DISABLED;
	rc = qpnp_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
	if (rc) {
		dev_err(&spmi->dev, "%s: qpnp_tm_shutdown_override() failed, rc=%d\n",
			__func__, rc);
		goto err_cancel_work;
	}

	chip->tz_dev = thermal_zone_device_register(tm_name, TRIP_NUM, chip,
			tz_ops, 0, 0, 0, 0);
	if (chip->tz_dev == NULL) {
		dev_err(&spmi->dev, "%s: thermal_zone_device_register() failed.\n",
			__func__);
		rc = -ENODEV;
		goto err_cancel_work;
	}

	rc = request_irq(chip->irq, qpnp_tm_isr, IRQF_TRIGGER_RISING, tm_name,
			chip);
	if (rc < 0) {
		dev_err(&spmi->dev, "%s: request_irq(%d) failed: %d\n",
			__func__, chip->irq, rc);
		goto err_free_tz;
	}

	return 0;

err_free_tz:
	thermal_zone_device_unregister(chip->tz_dev);
err_cancel_work:
	cancel_delayed_work_sync(&chip->irq_work);
	kfree(chip->tm_name);
free_chip:
	dev_set_drvdata(&spmi->dev, NULL);
	kfree(chip);
	return rc;
}
Exemple #17
0
static int __devinit qpnp_leds_probe(struct spmi_device *spmi)
{
	struct qpnp_led_data *led, *led_array;
	struct resource *led_resource;
	struct device_node *node, *temp;
	int rc, i, num_leds = 0, parsed_leds = 0;
	const char *led_label;

	node = spmi->dev.of_node;
	if (node == NULL)
		return -ENODEV;

	temp = NULL;
	while ((temp = of_get_next_child(node, temp)))
		num_leds++;

	if (!num_leds)
		return -ECHILD;

	led_array = devm_kzalloc(&spmi->dev,
		(sizeof(struct qpnp_led_data) * num_leds), GFP_KERNEL);
	if (!led_array) {
		dev_err(&spmi->dev, "Unable to allocate memory\n");
		return -ENOMEM;
	}

	for_each_child_of_node(node, temp) {
		led = &led_array[parsed_leds];
		led->num_leds = num_leds;
		led->spmi_dev = spmi;

		led_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
		if (!led_resource) {
			dev_err(&spmi->dev, "Unable to get LED base address\n");
			rc = -ENXIO;
			goto fail_id_check;
		}
		led->base = led_resource->start;

		rc = of_property_read_string(temp, "label", &led_label);
		if (rc < 0) {
			dev_err(&led->spmi_dev->dev,
				"Failure reading label, rc = %d\n", rc);
			goto fail_id_check;
		}

		rc = of_property_read_string(temp, "linux,name",
			&led->cdev.name);
		if (rc < 0) {
			dev_err(&led->spmi_dev->dev,
				"Failure reading led name, rc = %d\n", rc);
			goto fail_id_check;
		}

		rc = of_property_read_u32(temp, "qcom,max-current",
			&led->max_current);
		if (rc < 0) {
			dev_err(&led->spmi_dev->dev,
				"Failure reading max_current, rc =  %d\n", rc);
			goto fail_id_check;
		}

		rc = of_property_read_u32(temp, "qcom,id", &led->id);
		if (rc < 0) {
			dev_err(&led->spmi_dev->dev,
				"Failure reading led id, rc =  %d\n", rc);
			goto fail_id_check;
		}

		rc = qpnp_get_common_configs(led, temp);
		if (rc) {
			dev_err(&led->spmi_dev->dev,
				"Failure reading common led configuration," \
				" rc = %d\n", rc);
			goto fail_id_check;
		}

		led->cdev.brightness_set    = qpnp_led_set;
		led->cdev.brightness_get    = qpnp_led_get;

		if (strncmp(led_label, "wled", sizeof("wled")) == 0) {
			rc = qpnp_get_config_wled(led, temp);
			if (rc < 0) {
				dev_err(&led->spmi_dev->dev,
					"Unable to read wled config data\n");
				goto fail_id_check;
			}
		} else if (strncmp(led_label, "flash", sizeof("flash"))
				== 0) {
			rc = qpnp_get_config_flash(led, temp);
			if (rc < 0) {
				dev_err(&led->spmi_dev->dev,
					"Unable to read flash config data\n");
				goto fail_id_check;
			}
		} else if (strncmp(led_label, "rgb", sizeof("rgb")) == 0) {
			rc = qpnp_get_config_rgb(led, temp);
			if (rc < 0) {
				dev_err(&led->spmi_dev->dev,
					"Unable to read rgb config data\n");
				goto fail_id_check;
			}
		} else {
			dev_err(&led->spmi_dev->dev, "No LED matching label\n");
			rc = -EINVAL;
			goto fail_id_check;
		}

		spin_lock_init(&led->lock);

		rc =  qpnp_led_initialize(led);
		if (rc < 0)
			goto fail_id_check;

		rc = qpnp_led_set_max_brightness(led);
		if (rc < 0)
			goto fail_id_check;

		rc = led_classdev_register(&spmi->dev, &led->cdev);
		if (rc) {
			dev_err(&spmi->dev, "unable to register led %d,rc=%d\n",
						 led->id, rc);
			goto fail_id_check;
		}
		/* configure default state */
		if (led->default_on) {
			led->cdev.brightness = led->cdev.max_brightness;
			if (led->turn_off_delay_ms > 0)
				qpnp_led_turn_off(led);
		} else
			led->cdev.brightness = LED_OFF;

		qpnp_led_set(&led->cdev, led->cdev.brightness);

		parsed_leds++;
	}
static int spm_regulator_probe(struct spmi_device *spmi)
{
	struct regulator_config reg_config = {};
	struct device_node *node = spmi->dev.of_node;
	struct regulator_init_data *init_data;
	struct spm_vreg *vreg;
	struct resource *res;
	bool bypass_spm;
	int rc;

	if (!node) {
		dev_err(&spmi->dev, "%s: device node missing\n", __func__);
		return -ENODEV;
	}

	bypass_spm = of_property_read_bool(node, "qcom,bypass-spm");
	if (!bypass_spm) {
		rc = msm_spm_probe_done();
		if (rc) {
			if (rc != -EPROBE_DEFER)
				dev_err(&spmi->dev, "%s: spm unavailable, rc=%d\n",
					__func__, rc);
			return rc;
		}
	}

	vreg = devm_kzalloc(&spmi->dev, sizeof(*vreg), GFP_KERNEL);
	if (!vreg) {
		pr_err("allocation failed.\n");
		return -ENOMEM;
	}
	vreg->spmi_dev = spmi;
	vreg->bypass_spm = bypass_spm;

	res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&spmi->dev, "%s: node is missing base address\n",
			__func__);
		return -EINVAL;
	}
	vreg->spmi_base_addr = res->start;

	rc = qpnp_smps_check_type(vreg);
	if (rc)
		return rc;

	/* Specify CPU 0 as default in order to handle shared regulator case. */
	vreg->cpu_num = 0;
	of_property_read_u32(vreg->spmi_dev->dev.of_node, "qcom,cpu-num",
						&vreg->cpu_num);

	/*
	 * The regulator must be initialized to range 0 or range 1 during
	 * PMIC power on sequence.  Once it is set, it cannot be changed
	 * dynamically.
	 */
	if (vreg->regulator_type == QPNP_TYPE_FTS2)
		rc = qpnp_fts_init_range(vreg, &fts2_range0, &fts2_range1);
	else if (vreg->regulator_type == QPNP_TYPE_FTS2p5)
		rc = qpnp_fts_init_range(vreg, &fts2p5_range0, &fts2p5_range1);
	else if (vreg->regulator_type == QPNP_TYPE_ULT_HF)
		rc = qpnp_ult_hf_init_range(vreg);
	if (rc)
		return rc;

	rc = qpnp_smps_init_voltage(vreg);
	if (rc)
		return rc;

	rc = qpnp_smps_init_mode(vreg);
	if (rc)
		return rc;

	rc = qpnp_smps_init_step_rate(vreg);
	if (rc)
		return rc;

	init_data = of_get_regulator_init_data(&spmi->dev, node);
	if (!init_data) {
		dev_err(&spmi->dev, "%s: unable to allocate memory\n",
				__func__);
		return -ENOMEM;
	}
	init_data->constraints.input_uV = init_data->constraints.max_uV;
	init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS
			| REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE;
	init_data->constraints.valid_modes_mask
				= REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE;

	if (!init_data->constraints.name) {
		dev_err(&spmi->dev, "%s: node is missing regulator name\n",
			__func__);
		return -EINVAL;
	}

	vreg->rdesc.name	= init_data->constraints.name;
	vreg->rdesc.type	= REGULATOR_VOLTAGE;
	vreg->rdesc.owner	= THIS_MODULE;
	vreg->rdesc.ops		= &spm_regulator_ops;
	vreg->rdesc.n_voltages
		= (vreg->range->max_uV - vreg->range->set_point_min_uV)
			/ vreg->range->step_uV + 1;

	reg_config.dev = &spmi->dev;
	reg_config.init_data = init_data;
	reg_config.driver_data = vreg;
	reg_config.of_node = node;
	vreg->rdev = regulator_register(&vreg->rdesc, &reg_config);
	if (IS_ERR(vreg->rdev)) {
		rc = PTR_ERR(vreg->rdev);
		dev_err(&spmi->dev, "%s: regulator_register failed, rc=%d\n",
			__func__, rc);
		return rc;
	}

	dev_set_drvdata(&spmi->dev, vreg);

	pr_info("name=%s, range=%s, voltage=%d uV, mode=%s, step rate=%d uV/us\n",
		vreg->rdesc.name,
		spm_regulator_using_range0(vreg) ? "LV" : "MV",
		vreg->uV,
		vreg->init_mode & QPNP_SMPS_MODE_PWM ? "PWM" :
		    (vreg->init_mode & QPNP_FTS2_MODE_AUTO ? "AUTO" : "PFM"),
		vreg->step_rate);

	return rc;
}