static int __devinit isl9519q_init_adapter(struct isl9519q_struct *isl_chg)
{
	int ret;
	struct i2c_client *client = isl_chg->client;
	struct isl_platform_data *pdata = client->dev.platform_data;

	isl_chg->adapter_hw_chg.type = CHG_TYPE_AC;
	isl_chg->adapter_hw_chg.rating = 2;
	isl_chg->adapter_hw_chg.name = "isl-adapter";
	isl_chg->adapter_hw_chg.start_charging = isl_adapter_start_charging;
	isl_chg->adapter_hw_chg.stop_charging = isl_adapter_stop_charging;
	isl_chg->adapter_hw_chg.charging_switched = isl9519q_charging_switched;

	ret = gpio_request(pdata->valid_n_gpio, "isl_charger_valid");
	if (ret) {
		dev_err(&client->dev, "%s gpio_request failed "
				      "for %d ret=%d\n",
			__func__, pdata->valid_n_gpio, ret);
		goto out;
	}

	ret = msm_charger_register(&isl_chg->adapter_hw_chg);
	if (ret) {
		dev_err(&client->dev,
			"%s msm_charger_register failed for ret =%d\n",
			__func__, ret);
		goto free_gpio;
	}

	ret = request_threaded_irq(client->irq, NULL,
				   isl_valid_handler,
				   IRQF_TRIGGER_FALLING |
				   IRQF_TRIGGER_RISING,
				   "isl_charger_valid", client);
	if (ret) {
		dev_err(&client->dev,
			"%s request_threaded_irq failed "
			"for %d ret =%d\n",
			__func__, client->irq, ret);
		goto unregister;
	}
	irq_set_irq_wake(client->irq, 1);

	ret = gpio_get_value_cansleep(isl_chg->valid_n_gpio);
	if (ret < 0) {
		dev_err(&client->dev,
			"%s gpio_get_value failed for %d ret=%d\n",
			__func__, pdata->valid_n_gpio, ret);
		/* assume absent */
		ret = 1;
	}
	if (!ret) {
		msm_charger_notify_event(&isl_chg->adapter_hw_chg,
				CHG_INSERTED_EVENT);
		isl_chg->present = 1;
	}

	return 0;

unregister:
	msm_charger_unregister(&isl_chg->adapter_hw_chg);
free_gpio:
	gpio_free(pdata->valid_n_gpio);
out:
	return ret;

}
Beispiel #2
0
static int __devinit max8903_probe(struct platform_device *pdev)
{
	struct max8903_struct *max_chg;
	struct device *dev = &pdev->dev;
	struct max8903_platform_data *pdata = pdev->dev.platform_data;
    struct pm8058_chip *chip;
	int ret = 0;
    
    //printk("%s\n", __func__);
	max_chg = kzalloc(sizeof(struct max8903_struct), GFP_KERNEL);
	if (max_chg == NULL) {
		dev_err(dev, "Cannot allocate memory.\n");
		return -ENOMEM;
	}
	
	saved_msm_chg = max_chg;
	
	if (pdata == NULL) {
		dev_err(&pdev->dev, "%s no platform data\n", __func__);
		ret = -EINVAL;
		goto out;
	}

	INIT_DELAYED_WORK(&max_chg->charge_work, max8903_charge);
	INIT_DELAYED_WORK(&max_chg->ac_charger, ac_charger_detect);
	wake_lock_init(&max_chg->wl, WAKE_LOCK_SUSPEND, "max8903");
    
	max_chg->dev = &pdev->dev;;
    max_chg->irq = pdata->irq;
    max_chg->cen = pdata->cen;
    max_chg->chg = pdata->chg;
    max_chg->flt = pdata->flt;
	max_chg->usus = pdata->usus;
	max_chg->dock_det = pdata->dock_det;
	max_chg->usb_chg_enable = 1;	/* enable usb charge */

	if (BOARD_NUM(hw_ver) == BOARD_NUM_V11)
		max_chg->adapter_hw_chg.type = CHG_TYPE_AC;
	else
		max_chg->adapter_hw_chg.type = CHG_TYPE_USB;
	max_chg->adapter_hw_chg.rating = 2;
	max_chg->adapter_hw_chg.name = "max8903-charger";
	max_chg->adapter_hw_chg.start_charging = max8903_start_charging;
	max_chg->adapter_hw_chg.stop_charging = max8903_stop_charging;
	max_chg->adapter_hw_chg.charging_switched = max8903_charging_switched;
    
	platform_set_drvdata(pdev, max_chg);

	ret = gpio_request(max_chg->cen, "CHARGER_CEN_N");
	if (ret) {
		dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n",
			__func__, max_chg->cen, ret);
		goto free_max_chg;
	}

	ret = gpio_request(max_chg->chg, "CHARGER_STATUS");
	if (ret) {
		dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n",
			__func__, max_chg->chg, ret);
		goto free_cen;
	}
    gpio_direction_input(max_chg->chg);

    ret = gpio_request(max_chg->flt, "CHARGER_FAULT_N");
	if (ret) {
		dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n",
			__func__, max_chg->flt, ret);
		goto free_chg;
	}    
    gpio_direction_input(max_chg->flt);

    ret = request_threaded_irq(gpio_to_irq(max_chg->flt),
                            NULL, max8903_fault,
                            IRQF_TRIGGER_FALLING ,"MAX8903 Fault", pdev);
    if (ret) {
        dev_err(dev, "Cannot request irq %d for Fault (%d)\n",
                gpio_to_irq(max_chg->flt), ret);
        goto free_flt;
    }

	ret = gpio_request(max_chg->usus, "USUS_CTRL");
	if (ret) {
		dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n",
			__func__, max_chg->usus, ret);
		goto err_flt_irq;
	}

	ret = gpio_request(max_chg->dock_det, "DOCK_DET");
	if (ret) {
		dev_err(max_chg->dev, "%s gpio_request failed for %d ret=%d\n",
			__func__, max_chg->dock_det, ret);
		goto free_usus;
	}
	gpio_direction_input(max_chg->dock_det);
    
	ret = msm_charger_register(&max_chg->adapter_hw_chg);
	if (ret) {
		dev_err(max_chg->dev,
			"%s msm_charger_register failed for ret =%d\n",
			__func__, ret);
		goto free_dock_det;
	}
	
	ret = device_create_file(max_chg->dev, &usb_chg_enable_attr);
	if (ret) {
		dev_err(max_chg->dev, "failed: create usb_chg_enable file\n");
	}
	
	ret = request_threaded_irq(max_chg->irq, NULL,
				   max_valid_handler,
				   IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
				   "max_valid_handler", pdev);
	if (ret) {
		dev_err(max_chg->dev,
			"%s request_threaded_irq failed for %d ret =%d\n",
			__func__, max_chg->irq, ret);
		goto unregister;
	}
	set_irq_wake(max_chg->irq, 1);

    chip = get_irq_data(max_chg->irq);
    ret = pm8058_irq_get_rt_status(chip, max_chg->irq);
	if (ret) {
	#if 0
		if (!gpio_get_value_cansleep(max_chg->dock_det))	/* Dock insert, think it as AC charger */
			max_chg->adapter_hw_chg.type = CHG_TYPE_AC;
		msm_charger_notify_event(&max_chg->adapter_hw_chg,
				CHG_INSERTED_EVENT);
	#else
		/* Charger inserted, but not a valid USB charger
		 * think it as a AC charger
		 */
		if (USB_CHG_TYPE__INVALID == cur_chg_type)
			max_chg->adapter_hw_chg.type = CHG_TYPE_AC;
		
		msm_charger_notify_event(&max_chg->adapter_hw_chg,
				CHG_INSERTED_EVENT);
	#endif
		max_chg->present = 1;
		wake_lock(&max_chg->wl);
	}

	msm_register_usb_charger_state(max8903_usb_charger_state);

	pr_info("%s OK chg_present=%d\n", __func__, max_chg->present);
	return 0;

unregister:
	msm_charger_unregister(&max_chg->adapter_hw_chg);
free_dock_det:
	gpio_free(max_chg->dock_det);
free_usus:
    gpio_free(max_chg->usus);
err_flt_irq:
    free_irq(gpio_to_irq(max_chg->flt), pdev);
free_flt:
    gpio_free(max_chg->flt);
free_chg:
    gpio_free(max_chg->chg);
free_cen:
    gpio_free(max_chg->cen);
free_max_chg:
	kfree(max_chg);
out:
	return ret;
}
static int __devinit isl9519q_probe(struct i2c_client *client,
				    const struct i2c_device_id *id)
{
	struct isl_platform_data *pdata;
	struct isl9519q_struct *isl_chg;
	int ret;

	ret = 0;
	pdata = client->dev.platform_data;

	if (pdata == NULL) {
		dev_err(&client->dev, "%s no platform data\n", __func__);
		ret = -EINVAL;
		goto out;
	}

	if (!i2c_check_functionality(client->adapter,
				I2C_FUNC_SMBUS_WORD_DATA)) {
		ret = -EIO;
		goto out;
	}

	isl_chg = kzalloc(sizeof(*isl_chg), GFP_KERNEL);
	if (!isl_chg) {
		ret = -ENOMEM;
		goto out;
	}

	INIT_DELAYED_WORK(&isl_chg->charge_work, isl9519q_charge);
	isl_chg->client = client;
	isl_chg->chgcurrent = pdata->chgcurrent;
	isl_chg->term_current = pdata->term_current;
	isl_chg->input_current = pdata->input_current;
	isl_chg->max_system_voltage = pdata->max_system_voltage;
	isl_chg->min_system_voltage = pdata->min_system_voltage;
	isl_chg->valid_n_gpio = pdata->valid_n_gpio;

	/* h/w ignores lower 7 bits of charging current and input current */
	isl_chg->chgcurrent &= ~0x7F;
	isl_chg->input_current &= ~0x7F;

	isl_chg->adapter_hw_chg.type = CHG_TYPE_AC;
	isl_chg->adapter_hw_chg.rating = 2;
	isl_chg->adapter_hw_chg.name = "isl-adapter";
	isl_chg->adapter_hw_chg.start_charging = isl9519q_start_charging;
	isl_chg->adapter_hw_chg.stop_charging = isl9519q_stop_charging;
	isl_chg->adapter_hw_chg.charging_switched = isl9519q_charging_switched;

	if (pdata->chg_detection_config) {
		ret = pdata->chg_detection_config();
		if (ret) {
			dev_err(&client->dev, "%s valid config failed ret=%d\n",
				__func__, ret);
			goto free_isl_chg;
		}
	}

	ret = gpio_request(pdata->valid_n_gpio, "isl_charger_valid");
	if (ret) {
		dev_err(&client->dev, "%s gpio_request failed for %d ret=%d\n",
			__func__, pdata->valid_n_gpio, ret);
		goto free_isl_chg;
	}

	i2c_set_clientdata(client, isl_chg);

	ret = msm_charger_register(&isl_chg->adapter_hw_chg);
	if (ret) {
		dev_err(&client->dev,
			"%s msm_charger_register failed for ret =%d\n",
			__func__, ret);
		goto free_gpio;
	}

	ret = request_threaded_irq(client->irq, NULL,
				   isl_valid_handler,
				   IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
				   "isl_charger_valid", client);
	if (ret) {
		dev_err(&client->dev,
			"%s request_threaded_irq failed for %d ret =%d\n",
			__func__, client->irq, ret);
		goto unregister;
	}
	set_irq_wake(client->irq, 1);

	isl_chg->max_system_voltage &= MAX_VOLTAGE_REG_MASK;
	isl_chg->min_system_voltage &= MIN_VOLTAGE_REG_MASK;
	if (isl_chg->max_system_voltage == 0)
		isl_chg->max_system_voltage = DEFAULT_MAX_VOLTAGE_REG_VALUE;
	if (isl_chg->min_system_voltage == 0)
		isl_chg->min_system_voltage = DEFAULT_MIN_VOLTAGE_REG_VALUE;

	ret = isl9519q_write_reg(isl_chg->client, MAX_SYS_VOLTAGE_REG,
			isl_chg->max_system_voltage);
	if (ret) {
		dev_err(&client->dev,
			"%s couldnt write to MAX_SYS_VOLTAGE_REG ret=%d\n",
			__func__, ret);
		goto free_irq;
	}

	ret = isl9519q_write_reg(isl_chg->client, MIN_SYS_VOLTAGE_REG,
			isl_chg->min_system_voltage);
	if (ret) {
		dev_err(&client->dev,
			"%s couldnt write to MIN_SYS_VOLTAGE_REG ret=%d\n",
			__func__, ret);
		goto free_irq;
	}

	if (isl_chg->input_current) {
		ret = isl9519q_write_reg(isl_chg->client,
				INPUT_CURRENT_REG,
				isl_chg->input_current);
		if (ret) {
			dev_err(&client->dev,
				"%s couldnt write INPUT_CURRENT_REG ret=%d\n",
				__func__, ret);
			goto free_irq;
		}
	}

	ret = gpio_get_value_cansleep(isl_chg->valid_n_gpio);
	if (ret < 0) {
		dev_err(&client->dev,
			"%s gpio_get_value failed for %d ret=%d\n", __func__,
			pdata->valid_n_gpio, ret);
		/* assume absent */
		ret = 1;
	}
	if (!ret) {
		msm_charger_notify_event(&isl_chg->adapter_hw_chg,
				CHG_INSERTED_EVENT);
		isl_chg->present = 1;
	}

	pr_debug("%s OK chg_present=%d\n", __func__, isl_chg->present);
	return 0;

free_irq:
	free_irq(client->irq, NULL);
unregister:
	msm_charger_unregister(&isl_chg->adapter_hw_chg);
free_gpio:
	gpio_free(pdata->valid_n_gpio);
free_isl_chg:
	kfree(isl_chg);
out:
	return ret;
}
static int __devinit pm8058_charger_probe(struct platform_device *pdev)
{
	int ret;	
	struct pm8058_charger_platform_data *pdata;
	struct msm_hardware_charger *pchg;

	pdata = pdev->dev.platform_data;

	if(!pdata) {
		pr_err("%s: no platform_data passed in. \n", __func__);
		return -EFAULT;
	}

	pchg = kzalloc(sizeof *pchg, GFP_KERNEL);
	if (pchg == NULL) {
		pr_err("%s kzalloc failed\n", __func__);
		return -ENOMEM;
	}

	pchg->chg_detection_config = pdata->chg_detection_config;
	pchg->get_charger_status = pdata->get_charger_status;
	pchg->pdev = pdev;
	pchg->gpio_num = pdata->gpio_num;
	pchg->rating = pdata->rating;

	pchg->charger.name = pdata->name;
	if(pdata->rating == 2) {
		pchg->charger.type = POWER_SUPPLY_TYPE_MAINS;
	} else if(pdata->rating == 1) {
		pchg->charger.type = POWER_SUPPLY_TYPE_USB;
	} else {
		goto error_type;
	}

	pchg->charger.supplied_to = msm_power_supplied_to;
	pchg->charger.num_supplicants = ARRAY_SIZE(msm_power_supplied_to);
	pchg->charger.properties = msm_power_props;
	pchg->charger.num_properties = ARRAY_SIZE(msm_power_props);
	pchg->charger.get_property = charger_get_property_s7pro;

//
//#ifdef CONFIG_HAS_EARLYSUSPEND
//	pchg->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
//	pchg->early_suspend.suspend = s7pro_charger_early_suspend;
//	pchg->early_suspend.resume = s7pro_charger_late_resume;
//	register_early_suspend(&pchg->early_suspend);
//#endif
//

	dev_set_drvdata(&pdev->dev, pchg);

	if(pchg->chg_detection_config(1, pchg->gpio_num)) {
		pr_err("%s, init config fail. \n", __func__);
		goto error_type;
	}

	ret = request_irqs(pchg);
	if (ret) {
		pr_err("%s: couldnt register interrupts\n", __func__);
		goto error_type;
	}

	ret = msm_charger_register(pchg);
	if(ret) {
		pr_err("%s register charger failed ret=%d\n",
			__func__, ret);
		goto register_fail;
	}

	/* determine what state the charger is in */
	pm8058_chg_determine_initial_state(pchg);

	return 0;
	
register_fail:
	free_irqs(pchg);
error_type:
	kfree(pchg);
	return -EFAULT;
 
}