Android max17044平台驱动注册


#ifdef CONFIG_BATTERY_MAX17040#include <linux/max17040_battery.h>static int max17043_charger_online(void){int res = 0;gpio_request(S5PV210_GPH1(6), "GPH1_6");    s3c_gpio_cfgpin(S5PV210_GPH1(6), S3C_GPIO_INPUT);    res = gpio_get_value(S5PV210_GPH1(6));gpio_free(S5PV210_GPH1(6));return res;}//static int max17043_battery_online(void)static int max17043_ac_online(void){return max17043_charger_online();}static int max17043_charger_enable(void){int res = 0;gpio_request(S5PV210_GPH0(5), "GPH0_5");    s3c_gpio_cfgpin(S5PV210_GPH0(5), S3C_GPIO_INPUT);    res = gpio_get_value(S5PV210_GPH0(5));gpio_free(S5PV210_GPH0(5));return res>0 ? 0:1;}static struct max17040_platform_data max17043_plat = {.ac_online = max17043_ac_online,//.battery_online = max17043_battery_online,.charger_online = max17043_charger_online,.charger_enable = max17043_charger_enable,};#endifstatic struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {#ifdef CONFIG_BATTERY_MAX17040{ I2C_BOARD_INFO("max17043", 0x36), .platform_data = &max17043_plat},     /* MAX17043 */#endif};


在内核中配置Power supply class support中打开 Maxim MAX17040 Fuel Gauge的支持
在include/linux/max17040_battery.h中添加如下代码
struct max17040_platform_data {int (*ac_online)(void);int (*battery_online)(void);int (*charger_online)(void);int (*charger_enable)(void);};



并修改drivers/power/max17040_battery.c

#define MAX17040_VCELL_MSB0x02#define MAX17040_VCELL_LSB0x03#define MAX17040_SOC_MSB0x04#define MAX17040_SOC_LSB0x05#define MAX17040_MODE_MSB0x06#define MAX17040_MODE_LSB0x07#define MAX17040_VER_MSB0x08#define MAX17040_VER_LSB0x09#define MAX17040_RCOMP_MSB0x0C#define MAX17040_RCOMP_LSB0x0D#define MAX17040_CMD_MSB0xFE#define MAX17040_CMD_LSB0xFF#define MAX17040_DELAY1000#define MAX17040_BATTERY_FULL95#undef _DPRINT_#ifdef _DPRINT_#define dprint(fmt, arg...) printk(fmt, ##arg)#else#define dprint(fmt, arg...)#endifstruct max17040_chip {struct i2c_client*client;struct delayed_workwork;struct power_supplybattery;struct power_supplyac;//struct power_supplyusb;struct max17040_platform_data*pdata;/* State Of Connect */int online;/* battery voltage */int vcell;/* battery capacity */int soc;/* State Of Charge */int status;int ac_online;};static int max17040_get_property(struct power_supply *psy,    enum power_supply_property psp,    union power_supply_propval *val){struct max17040_chip *chip = container_of(psy,struct max17040_chip, battery);switch (psp) {case POWER_SUPPLY_PROP_STATUS:val->intval = chip->status;break;case POWER_SUPPLY_PROP_ONLINE:val->intval = chip->online;break;case POWER_SUPPLY_PROP_VOLTAGE_NOW:val->intval = chip->vcell;break;case POWER_SUPPLY_PROP_CAPACITY:val->intval = chip->soc;break;default:return -EINVAL;}return 0;}static int ac_get_property(struct power_supply *psy,    enum power_supply_property psp,    union power_supply_propval *val){struct max17040_chip *chip = container_of(psy,struct max17040_chip, ac);switch (psp) {case POWER_SUPPLY_PROP_STATUS:val->intval = chip->status;break;case POWER_SUPPLY_PROP_ONLINE:val->intval = chip->ac_online;break;case POWER_SUPPLY_PROP_VOLTAGE_NOW:val->intval = chip->vcell;break;case POWER_SUPPLY_PROP_CAPACITY:val->intval = chip->soc;break;default:return -EINVAL;}return 0;}static int max17040_write_reg(struct i2c_client *client, int reg, u8 value){int ret;ret = i2c_smbus_write_byte_data(client, reg, value);if (ret < 0)dev_err(&client->dev, "%s: err %d\n", __func__, ret);return ret;}static int max17040_read_reg(struct i2c_client *client, int reg){int ret;ret = i2c_smbus_read_byte_data(client, reg);if (ret < 0)dev_err(&client->dev, "%s: err %d\n", __func__, ret);return ret;}static void max17040_reset(struct i2c_client *client){max17040_write_reg(client, MAX17040_CMD_MSB, 0x54);max17040_write_reg(client, MAX17040_CMD_LSB, 0x00);max17040_write_reg(client, MAX17040_RCOMP_MSB, 0x97);max17040_write_reg(client, MAX17040_RCOMP_LSB, 0x30);}static void max17040_get_vcell(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);u8 msb;u8 lsb;msb = max17040_read_reg(client, MAX17040_VCELL_MSB);lsb = max17040_read_reg(client, MAX17040_VCELL_LSB);//chip->vcell = (msb << 4) + (lsb >> 4);chip->vcell = (((msb << 4) + (lsb >> 4)) * 25 ) / 10;dprint("*%s(): vcell 0x%04x Vcc = %d mV\n", __func__, chip->vcell, (chip->vcell * 25)/10);}static void max17040_get_soc(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);u8 msb;u8 lsb;msb = max17040_read_reg(client, MAX17040_SOC_MSB);lsb = max17040_read_reg(client, MAX17040_SOC_LSB);chip->soc = (msb<<8) + lsb;dprint("*%s(): msb 0x%02x lsb 0x%02x\n", __func__, msb, lsb);}static void max17040_get_version(struct i2c_client *client){u8 msb;u8 lsb;msb = max17040_read_reg(client, MAX17040_VER_MSB);lsb = max17040_read_reg(client, MAX17040_VER_LSB);dprint("*%s(): msb 0x%02x lsb 0x%02x\n", __func__, msb, lsb);dev_info(&client->dev, "MAX17040 Fuel-Gauge Ver %d%d\n", msb, lsb);}static void max17040_get_online(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);if (chip->pdata->battery_online)chip->online = chip->pdata->battery_online();elsechip->online = 1;}static void max17040_get_ac_online(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);if (chip->pdata->ac_online)chip->ac_online = chip->pdata->ac_online();elsechip->online = 1;}static void max17040_get_status(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);if (!chip->pdata->charger_online || !chip->pdata->charger_enable) {chip->status = POWER_SUPPLY_STATUS_UNKNOWN;return;}if (chip->pdata->charger_online()) {if (chip->pdata->charger_enable())chip->status = POWER_SUPPLY_STATUS_CHARGING;elsechip->status = POWER_SUPPLY_STATUS_NOT_CHARGING;} else {chip->status = POWER_SUPPLY_STATUS_DISCHARGING;}if (chip->soc > MAX17040_BATTERY_FULL)chip->status = POWER_SUPPLY_STATUS_FULL;}static void max17040_work(struct work_struct *work){struct max17040_chip *chip;int old_online, old_ac_online, old_vcell, old_soc;chip = container_of(work, struct max17040_chip, work.work);old_ac_online = chip->ac_online;old_online = chip->online;//old_usb_online = chip->usb_online;old_vcell = chip->vcell;old_soc = chip->soc;max17040_get_vcell(chip->client);max17040_get_soc(chip->client);max17040_get_online(chip->client);max17040_get_ac_online(chip->client);max17040_get_status(chip->client);if ((old_vcell != chip->vcell) || (old_soc != chip->soc)) {//(3)、如果电池信息有变化,就上报系统;/* printk(KERN_DEBUG "power_supply_changed for battery\n"); */power_supply_changed(&chip->battery);}#if 0//#if !defined(CONFIG_CHARGER_PM2301)//(4)、如果用PM2301充电IC,USB充电功能不用;if (old_usb_online != chip->usb_online) {/* printk(KERN_DEBUG "power_supply_changed for usb\n"); */power_supply_changed(&chip->usb);}#endifif (old_online != chip->online) {//(5)、如果有DC插入,则更新充电状态;power_supply_changed(&chip->battery);}if (old_ac_online != chip->ac_online) {power_supply_changed(&chip->ac);}schedule_delayed_work(&chip->work, MAX17040_DELAY);}static enum power_supply_property max17040_battery_props[] = {POWER_SUPPLY_PROP_STATUS,POWER_SUPPLY_PROP_ONLINE,POWER_SUPPLY_PROP_VOLTAGE_NOW,POWER_SUPPLY_PROP_CAPACITY,};static enum power_supply_property ac_adapter_props[] = {POWER_SUPPLY_PROP_STATUS,POWER_SUPPLY_PROP_ONLINE,POWER_SUPPLY_PROP_VOLTAGE_NOW,POWER_SUPPLY_PROP_CAPACITY,};static int __devinit max17040_probe(struct i2c_client *client,const struct i2c_device_id *id){struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);struct max17040_chip *chip;int ret;dprint("+%s()\n", __func__);if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))return -EIO;chip = kzalloc(sizeof(*chip), GFP_KERNEL);if (!chip)return -ENOMEM;chip->client = client;chip->pdata = client->dev.platform_data;i2c_set_clientdata(client, chip);chip->battery.name= "battery";chip->battery.type= POWER_SUPPLY_TYPE_BATTERY;chip->battery.get_property= max17040_get_property;chip->battery.properties= max17040_battery_props;chip->battery.num_properties= ARRAY_SIZE(max17040_battery_props);ret = power_supply_register(&client->dev, &chip->battery);if (ret) {dev_err(&client->dev, "failed: power supply register\n");kfree(chip);return ret;}chip->ac.name= "ac";chip->ac.type= POWER_SUPPLY_TYPE_MAINS;chip->ac.get_property= ac_get_property;chip->ac.properties= ac_adapter_props;chip->ac.num_properties= ARRAY_SIZE(ac_adapter_props);chip->ac.external_power_changed = NULL;ret = power_supply_register(&client->dev, &chip->ac);if (ret) {dev_err(&client->dev, "failed: power supply register\n");power_supply_unregister(&chip->battery);kfree(chip);return ret;}max17040_reset(client);max17040_get_version(client);INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17040_work);schedule_delayed_work(&chip->work, MAX17040_DELAY);//for(;;)ret = max17040_read_reg(client, MAX17040_VER_LSB);dprint("-%s()\n", __func__);return 0;}static int __devexit max17040_remove(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);power_supply_unregister(&chip->battery);cancel_delayed_work(&chip->work);kfree(chip);return 0;}#ifdef CONFIG_PMstatic int max17040_suspend(struct i2c_client *client,pm_message_t state){struct max17040_chip *chip = i2c_get_clientdata(client);cancel_delayed_work(&chip->work);return 0;}static int max17040_resume(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);schedule_delayed_work(&chip->work, MAX17040_DELAY);return 0;}#else#define max17040_suspend NULL#define max17040_resume NULL#endif /* CONFIG_PM */static const struct i2c_device_id max17040_id[] = {{ "max17040", 0 },{ "max17043", 0 },{ }};MODULE_DEVICE_TABLE(i2c, max17040_id);static struct i2c_driver max17040_i2c_driver = {.driver= {.name= "max17040",},.probe= max17040_probe,.remove= __devexit_p(max17040_remove),.suspend= max17040_suspend,.resume= max17040_resume,.id_table= max17040_id,};static int __init max17040_init(void){return i2c_add_driver(&max17040_i2c_driver);}module_init(max17040_init);static void __exit max17040_exit(void){i2c_del_driver(&max17040_i2c_driver);}module_exit(max17040_exit);MODULE_AUTHOR("Minkyu Kang <mk7.kang@samsung.com>");MODULE_DESCRIPTION("MAX17040 Fuel Gauge");MODULE_LICENSE("GPL");


更多相关文章

  1. Android(安卓)按键处理(驱动层到上层)架构
  2. S3C6410(M8用的) 移植Android(安卓)内核
  3. Ubuntu下编译android的linux内核
  4. SEAndroid简介
  5. android 按键
  6. 利用BLCR加快Android的启动过程
  7. Android(安卓)4.3新特性——SElinux简介
  8. Ubuntu下编译android的linux内核
  9. 如何下载并编译Android4.0内核源码goldfish(图文)

随机推荐

  1. 小学生都开始学Python了,你还不抓紧提升技
  2. 我们知道ArrayList是线程不安全,请设计一
  3. kube-scheduler 源码解析
  4. 入门版本 MacBook Air 带给我无限惊喜
  5. 课程表、用户表单代码
  6. 利用Azure虚拟机安装Dynamics 365 Custom
  7. Dynamics CRM定制子网格添加按钮实例之一
  8. Dynamics 365利用HTML页面创建实体记录并
  9. 使用docker Registry快速搭建私有镜像仓
  10. 利用Azure虚拟机安装Dynamics 365 Custom