1. init/exit
- static int __init lp3925_init(void)
- {
- int ret = 0;
- ret = i2c_add_driver(&lp3925_driver);
- if (ret) {
- printk(KERN_WARNING "lp3925: Driver registration failed, \
- module not inserted.\n");
- return ret;
- }
- return ret;
- }
- static void __exit lp3925_exit(void)
- {
- i2c_del_driver(&lp3925_driver);
- }
- subsys_initcall(lp3925_init);
- module_exit(lp3925_exit);
2. lp3925_driver
- static struct i2c_driver lp3925_driver = {
- .driver = {
- .name = "lp3925",
- },
- .probe = lp3925_probe,
- .remove = __devexit_p(lp3925_remove),
- .id_table = lp3925_id,
- };
lp3925_id
- static const struct i2c_device_id lp3925_id[] = {
- { "lp3925", 0 },
- { },
- };
3. lp3925_probe()
- static int __devinit lp3925_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
- {
- struct lp3925_platform_data *pdata;
- struct lp3925_data *data;
- int err = 0;
- pdata = client->dev.platform_data;
- if (pdata == NULL) {
- dev_dbg(&client->dev, "No platform data\n");
- return -EINVAL;
- }
- if ((pdata->buck1_dvs > LP3925_BUCK_DVS_MAX)
- || (pdata->buck2_dvs > LP3925_BUCK_DVS_MAX)) {
- dev_dbg(&client->dev, "Invalid platform data\n");
- return -EINVAL;
- }
- if (!(data = kzalloc(sizeof(struct lp3925_data), GFP_KERNEL)))
- return -ENOMEM;
- lp3925_client = client;
-
- data->pdata = pdata;
- data->irq_mask = 0xffffffff;
- data->irq_gpio = pdata->irq_gpio;
- data->irq = gpio_to_irq(pdata->irq_gpio);
- i2c_set_clientdata(client, data);
- mutex_init(&data->power_lock);
- mutex_init(&data->adc_lock);
- mutex_init(&data->reg_lock);
-
- if ((err = lp3925_hw_init(data)) != 0)
- goto exit;
-
- pmic_ops_set(&lp3925_pmic_ops);
- return 0;
- exit:
- kfree(data);
- return err;
- }
4. 解析 pdata
= client->dev.platform_data; 这里的platform_data 在board.c中初始化:
- #if defined(CONFIG_COMIP_LP3925)
-
- {LP3925_INT_PIN, MFP_PIN_MODE_GPIO},
- #endif
-
- #if defined(CONFIG_COMIP_LP3925)
- static struct lp3925_ldo_ctrl_map comip_lp3925_ldo_ctrl_map[] = {
- {LP3925_LDO_1, LP3925_LDO_CTRL_ALWAYS_ON, LP3925_LDO_CTRL_GPIO_ID_NONE, 2850},
- {LP3925_LDO_2, LP3925_LDO_CTRL_REG21, LP3925_LDO_CTRL_GPIO_ID_NONE, 1800},
- {LP3925_LDO_3, LP3925_LDO_CTRL_REG00, LP3925_LDO_CTRL_GPIO_ID_NONE, 2200},
- {LP3925_LDO_5, LP3925_LDO_CTRL_GPIO4, LP3925_LDO_CTRL_GPIO_ID_NONE, 1800},
- {LP3925_LDO_6, LP3925_LDO_CTRL_REG00, LP3925_LDO_CTRL_GPIO_ID_NONE, 3000},
- {LP3925_LDO_7, LP3925_LDO_CTRL_REG01, LP3925_LDO_CTRL_GPIO_ID_NONE, 1800},
- {LP3925_LDO_11, LP3925_LDO_CTRL_REG10, LP3925_LDO_CTRL_GPIO_ID_NONE, 2850},
- {LP3925_LDO_12, LP3925_LDO_CTRL_REG10, LP3925_LDO_CTRL_GPIO_ID_NONE, 3000},
- {LP3925_LDO_13, LP3925_LDO_CTRL_REG11, LP3925_LDO_CTRL_GPIO_ID_NONE, 2850},
- {LP3925_REFOUT, LP3925_LDO_CTRL_GPIO3, LP3925_LDO_CTRL_GPIO_ID_NONE, 2500},
- };
- static struct lp3925_ldo_module_map comip_lp3925_ldo_module_map[] = {
- {LP3925_LDO_2, PMIC_POWER_CAMERA_DIGITAL, 1, 0},
- {LP3925_LDO_3, PMIC_POWER_SWITCH, 0, 0},
- {LP3925_LDO_7, PMIC_POWER_CMMB_BB_CORE, 0, 0},
- {LP3925_LDO_6, PMIC_POWER_USIM, 0, 0},
- {LP3925_LDO_8, PMIC_POWER_RF_GSM_CORE, 0, 1},
- {LP3925_LDO_9, PMIC_POWER_RF_GSM_IO, 0, 1},
- {LP3925_LDO_10, PMIC_POWER_RF_TDD_CORE, 0, 1},
- {LP3925_LDO_11, PMIC_POWER_CMMB_IO, 0, 0},
- {LP3925_LDO_12, PMIC_POWER_SDIO, 0, 0},
- {LP3925_LDO_13, PMIC_POWER_CAMERA_IO, 1, 0},
- {LP3925_LDO_13, PMIC_POWER_CAMERA_CORE, 0, 0},
- {LP3925_LDO_13, PMIC_POWER_LCD_CORE, 0, 0},
- {LP3925_LDO_EXT_1, PMIC_POWER_LED, 0, 0},
- {LP3925_LDO_EXT_2, PMIC_POWER_VIBRATOR, 0, 0},
- };
- static struct lp3925_pin_map comip_lp3925_pin_map[] = {
- {LP3925_PIN_INP1, LP3925_PIN_INP_1000MV},
- {LP3925_PIN_INP2, LP3925_PIN_INP_1000MV},
- {LP3925_PIN_SINK1, LP3925_PIN_SINK1_125MA},
- {LP3925_PIN_SINK2, LP3925_PIN_SINK2_3_100MA},
- };
- static struct lp3925_platform_data comip_i2c_lp3925_info = {
- .irq_gpio = mfp_to_gpio(LP3925_INT_PIN),
- .ctrl_map = comip_lp3925_ldo_ctrl_map,
- .ctrl_map_num = ARRAY_SIZE(comip_lp3925_ldo_ctrl_map),
- .module_map = comip_lp3925_ldo_module_map,
- .module_map_num = ARRAY_SIZE(comip_lp3925_ldo_module_map),
- .pin_map = comip_lp3925_pin_map,
- .pin_map_num = ARRAY_SIZE(comip_lp3925_pin_map),
- .buck1_dvs = 1,
- .buck2_dvs = 3,
- };
- #endif
最后是i2c0_board_info中添加的I2C数据项:
- #if defined(CONFIG_COMIP_LP3925)
- {
- .type = "lp3925",
- .addr = 0x7e,
- .platform_data = &comip_i2c_lp3925_info,
- },
- #endif
一个LP3925重要的数据结构,表达了该芯片的各种属性,细节就不跟了,得跟datasheet联系:
-
- struct lp3925_platform_data {
- int irq_gpio;
- struct lp3925_pin_map* pin_map;
- int pin_map_num;
- struct lp3925_ldo_timing* ldo_timing;
- int ldo_timing_num;
- struct lp3925_ldo_pull_down* ldo_pull_down;
- int ldo_pull_down_num;
- struct lp3925_ldo_ctrl_map* ctrl_map;
- int ctrl_map_num;
- struct lp3925_ldo_module_map* module_map;
- int module_map_num;
-
- u8 buck1_dvs;
- u8 buck2_dvs;
- };
5. lp3925_hw_init()硬件初始化,芯片的各种初始化流程。
- static int lp3925_hw_init(struct lp3925_data *data)
- {
- int i;
- int ret;
-
- lp3925_reg_write(LP3925_REG_INT_MASK0, 0xff);
- lp3925_reg_write(LP3925_REG_INT_MASK1, 0xff);
-
- lp3925_reg_read(LP3925_REG_SILICON_ID, &data->silicon_id);
- lp3925_reg_read(LP3925_REG_EEPROM_VERSION_ID, &data->version_id);
-
- for (i = 0; i < LP3925_REG_ENABLE_NUM; i++)
- lp3925_reg_read(LP3925_REG_ENABLE_BASE + i, &data->enable_reg[i]);
-
- lp3925_reboot_init(data);
-
- lp3925_rtc_init(data);
-
- lp3925_pin_init(data);
-
- lp3925_power_init(data);
-
- ret = lp3925_irq_init(data);
- if (ret)
- goto exit;
- return 0;
- exit:
- return ret;
- }
6. pmic_ops_set(&lp3925_pmic_ops),这个函数在arch/arm/mach-xxx/xxx-pmic.c中。这里就有点设计PM模块了。
- int pmic_ops_set(struct pmic_ops *ops)
- {
- if (g_pmic_ops != NULL) {
- printk(KERN_ERR "set pmic_ops when pmic_ops is not NULL\n");
- return -EFAULT;
- }
- g_pmic_ops = ops;
- INIT_LIST_HEAD(&g_pmic_ops->list);
- spin_lock_init(&g_pmic_ops->cb_lock);
- return 0;
- }
- EXPORT_SYMBOL(pmic_ops_set);
pmic_ops
-
- struct pmic_ops {
-
- int (*reg_write)(u16 reg, u16 val);
- int (*reg_read)(u16 reg, u16 *pval);
-
- int (*event_mask)(int event);
- int (*event_unmask)(int event);
-
- int (*voltage_get)(u8 module, u8 param, int *pmv);
- int (*voltage_set)(u8 module, u8 param, int mv);
-
- int (*rtc_time_get)(struct rtc_time *tm);
- int (*rtc_time_set)(struct rtc_time *tm);
- int (*rtc_alarm_get)(u8 id, struct rtc_wkalrm *alrm);
- int (*rtc_alarm_set)(u8 id, struct rtc_wkalrm *alrm);
-
- int (*comp_state_get)(u8 id);
-
- int (*power_on_type_get)(void);
-
- int (*power_key_state_get)(void);
-
- struct list_head list;
-
- spinlock_t cb_lock;
- };
7. lp3925_pmic_ops, LP3925具体的pmic_ops.
- static struct pmic_ops lp3925_pmic_ops = {
- .reg_read = lp3925_pmu_reg_read,
- .reg_write = lp3925_pmu_reg_write,
- .event_mask = lp3925_event_mask,
- .event_unmask = lp3925_event_unmask,
- .voltage_get = lp3925_voltage_get,
- .voltage_set = lp3925_voltage_set,
- .rtc_time_get = lp3925_rtc_time_get,
- .rtc_time_set = lp3925_rtc_time_set,
- .rtc_alarm_get = lp3925_rtc_alarm_get,
- .rtc_alarm_set = lp3925_rtc_alarm_set,
- .comp_state_get = lp3925_comp_state_get,
- .power_key_state_get = lp3925_power_key_state_get,
- .power_on_type_get = lp3925_power_on_type_get,
- };
|