示例#1
0
static __devinit int wm831x_power_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_power *power;
	struct power_supply *usb;
	struct power_supply *battery;
	struct power_supply *wall;
	int ret, irq;

	power = kzalloc(sizeof(struct wm831x_power), GFP_KERNEL);
	if (power == NULL)
		return -ENOMEM;

	power->wm831x = wm831x;
	platform_set_drvdata(pdev, power);

	usb = &power->usb;
	battery = &power->battery;
	wall = &power->wall;

	/* We ignore configuration failures since we can still read back
	 * the status without enabling the charger.
	 */
	wm831x_config_battery(wm831x);
	wake_lock_init(&batt_wake_lock, WAKE_LOCK_SUSPEND, "batt_lock");

	wall->name = "wm831x-wall";
	wall->type = POWER_SUPPLY_TYPE_MAINS;
	wall->properties = wm831x_wall_props;
	wall->num_properties = ARRAY_SIZE(wm831x_wall_props);
	wall->get_property = wm831x_wall_get_prop;
	ret = power_supply_register(&pdev->dev, wall);
	if (ret)
		goto err_kmalloc;

	battery->name = "wm831x-battery";
	battery->properties = wm831x_bat_props;
	battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
	battery->get_property = wm831x_bat_get_prop;
	battery->use_for_apm = 1;
	ret = power_supply_register(&pdev->dev, battery);
	if (ret)
		goto err_wall;

	usb->name = "wm831x-usb",
	usb->type = POWER_SUPPLY_TYPE_USB;
	usb->properties = wm831x_usb_props;
	usb->num_properties = ARRAY_SIZE(wm831x_usb_props);
	usb->get_property = wm831x_usb_get_prop;
	ret = power_supply_register(&pdev->dev, usb);
	if (ret)
		goto err_battery;

	irq = platform_get_irq_byname(pdev, "SYSLO");
	ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq,
				   IRQF_TRIGGER_RISING, "System power low",
				   power);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n",
			irq, ret);
		goto err_usb;
	}

	irq = platform_get_irq_byname(pdev, "PWR SRC");
	ret = request_threaded_irq(irq, NULL, wm831x_pwr_src_irq,
				   IRQF_TRIGGER_RISING, "Power source",
				   power);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request PWR SRC IRQ %d: %d\n",
			irq, ret);
		goto err_syslo;
	}

#ifdef CONFIG_WM831X_WITH_BATTERY
	int i;
	for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
		irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
		ret = request_threaded_irq(irq, NULL, wm831x_bat_irq,
					   IRQF_TRIGGER_RISING,
					   wm831x_bat_irqs[i],
					   power);
		WM_BATT_DBG("%s: %s irq no %d\n", __FUNCTION__, wm831x_bat_irqs[i], irq);
		if (ret != 0) {
			dev_err(&pdev->dev,
				"Failed to request %s IRQ %d: %d\n",
				wm831x_bat_irqs[i], irq, ret);
			goto err_bat_irq;
		}
	}
#endif

	power->interval = TIMER_MS_COUNTS;
	power->batt_info.level = 100;
	power->batt_info.voltage   = 4200000;
	power->batt_info.online    = 1;
	power->batt_info.status    = POWER_SUPPLY_STATUS_DISCHARGING;
	power->batt_info.health    = POWER_SUPPLY_HEALTH_GOOD;

	wake_lock_init(&power->syslo_wake, WAKE_LOCK_SUSPEND, "wm831x_syslo_wake");
	INIT_WORK(&power->batt_work, wm831x_batt_work);
	setup_timer(&power->timer, wm831x_batt_timer_handler, (unsigned long)power);
	power->timer.expires = jiffies + msecs_to_jiffies(1000);
	add_timer(&power->timer);

	g_wm831x_power = power;
#ifdef CONFIG_POWER_ON_CHARGER_DISPLAY
	wm831x_batt_check(power);//xsf
#endif
	
	printk("%s:wm831x_power initialized\n",__FUNCTION__);
	power_test_sysfs_init();
	return ret;
	
#ifdef CONFIG_WM831X_WITH_BATTERY
err_bat_irq:
	for (; i >= 0; i--) {
		irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
		free_irq(irq, power);
	}
	irq = platform_get_irq_byname(pdev, "PWR SRC");
	free_irq(irq, power);
#endif

err_syslo:
	irq = platform_get_irq_byname(pdev, "SYSLO");
	free_irq(irq, power);
err_usb:
	power_supply_unregister(usb);
err_battery:
	power_supply_unregister(battery);
err_wall:
	power_supply_unregister(wall);
err_kmalloc:
	kfree(power);
	return ret;
}
static __devinit int wm831x_power_probe(struct platform_device *pdev)
{
	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
	struct wm831x_pdata *wm831x_pdata = wm831x->dev->platform_data;
	struct wm831x_power *power;
	struct power_supply *usb;
	struct power_supply *battery;
	struct power_supply *wall;
	int ret, irq, i;

	power = kzalloc(sizeof(struct wm831x_power), GFP_KERNEL);
	if (power == NULL)
		return -ENOMEM;

	power->wm831x = wm831x;
	platform_set_drvdata(pdev, power);

	usb = &power->usb;
	battery = &power->battery;
	wall = &power->wall;

	if (wm831x_pdata && wm831x_pdata->wm831x_num) {
		snprintf(power->wall_name, sizeof(power->wall_name),
			 "wm831x-wall.%d", wm831x_pdata->wm831x_num);
		snprintf(power->battery_name, sizeof(power->wall_name),
			 "wm831x-battery.%d", wm831x_pdata->wm831x_num);
		snprintf(power->usb_name, sizeof(power->wall_name),
			 "wm831x-usb.%d", wm831x_pdata->wm831x_num);
	} else {
		snprintf(power->wall_name, sizeof(power->wall_name),
			 "wm831x-wall");
		snprintf(power->battery_name, sizeof(power->wall_name),
			 "wm831x-battery");
		snprintf(power->usb_name, sizeof(power->wall_name),
			 "wm831x-usb");
	}

	/* We ignore configuration failures since we can still read back
	 * the status without enabling the charger.
	 */
	wm831x_config_battery(wm831x);

	wall->name = power->wall_name;
	wall->type = POWER_SUPPLY_TYPE_MAINS;
	wall->properties = wm831x_wall_props;
	wall->num_properties = ARRAY_SIZE(wm831x_wall_props);
	wall->get_property = wm831x_wall_get_prop;
	ret = power_supply_register(&pdev->dev, wall);
	if (ret)
		goto err_kmalloc;

	usb->name = power->usb_name,
	usb->type = POWER_SUPPLY_TYPE_USB;
	usb->properties = wm831x_usb_props;
	usb->num_properties = ARRAY_SIZE(wm831x_usb_props);
	usb->get_property = wm831x_usb_get_prop;
	ret = power_supply_register(&pdev->dev, usb);
	if (ret)
		goto err_wall;

	ret = wm831x_reg_read(wm831x, WM831X_CHARGER_CONTROL_1);
	if (ret < 0)
		goto err_wall;
	power->have_battery = ret & WM831X_CHG_ENA;

	if (power->have_battery) {
		    battery->name = power->battery_name;
		    battery->properties = wm831x_bat_props;
		    battery->num_properties = ARRAY_SIZE(wm831x_bat_props);
		    battery->get_property = wm831x_bat_get_prop;
		    battery->use_for_apm = 1;
		    ret = power_supply_register(&pdev->dev, battery);
		    if (ret)
			    goto err_usb;
	}

	irq = platform_get_irq_byname(pdev, "SYSLO");
	ret = request_threaded_irq(irq, NULL, wm831x_syslo_irq,
				   IRQF_TRIGGER_RISING, "System power low",
				   power);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request SYSLO IRQ %d: %d\n",
			irq, ret);
		goto err_battery;
	}

	irq = platform_get_irq_byname(pdev, "PWR SRC");
	ret = request_threaded_irq(irq, NULL, wm831x_pwr_src_irq,
				   IRQF_TRIGGER_RISING, "Power source",
				   power);
	if (ret != 0) {
		dev_err(&pdev->dev, "Failed to request PWR SRC IRQ %d: %d\n",
			irq, ret);
		goto err_syslo;
	}

	for (i = 0; i < ARRAY_SIZE(wm831x_bat_irqs); i++) {
		irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
		ret = request_threaded_irq(irq, NULL, wm831x_bat_irq,
					   IRQF_TRIGGER_RISING,
					   wm831x_bat_irqs[i],
					   power);
		if (ret != 0) {
			dev_err(&pdev->dev,
				"Failed to request %s IRQ %d: %d\n",
				wm831x_bat_irqs[i], irq, ret);
			goto err_bat_irq;
		}
	}

	return ret;

err_bat_irq:
	for (; i >= 0; i--) {
		irq = platform_get_irq_byname(pdev, wm831x_bat_irqs[i]);
		free_irq(irq, power);
	}
	irq = platform_get_irq_byname(pdev, "PWR SRC");
	free_irq(irq, power);
err_syslo:
	irq = platform_get_irq_byname(pdev, "SYSLO");
	free_irq(irq, power);
err_battery:
	if (power->have_battery)
		power_supply_unregister(battery);
err_usb:
	power_supply_unregister(usb);
err_wall:
	power_supply_unregister(wall);
err_kmalloc:
	kfree(power);
	return ret;
}