^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * TI LP8788 MFD - core interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2012 Texas Instruments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/mfd/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mfd/lp8788.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define MAX_LP8788_REGISTERS 0xA2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define MFD_DEV_SIMPLE(_name) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) .name = LP8788_DEV_##_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define MFD_DEV_WITH_ID(_name, _id) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) .name = LP8788_DEV_##_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) .id = _id, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define MFD_DEV_WITH_RESOURCE(_name, _resource, num_resource) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) .name = LP8788_DEV_##_name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) .resources = _resource, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) .num_resources = num_resource, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static struct resource chg_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Charger Interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .start = LP8788_INT_CHG_INPUT_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .end = LP8788_INT_PRECHG_TIMEOUT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) .name = LP8788_CHG_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .flags = IORESOURCE_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Power Routing Switch Interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) .start = LP8788_INT_ENTER_SYS_SUPPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) .end = LP8788_INT_EXIT_SYS_SUPPORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) .name = LP8788_PRSW_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) .flags = IORESOURCE_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* Battery Interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .start = LP8788_INT_BATT_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .end = LP8788_INT_NO_BATT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .name = LP8788_BATT_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .flags = IORESOURCE_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static struct resource rtc_irqs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) .start = LP8788_INT_RTC_ALARM1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) .end = LP8788_INT_RTC_ALARM2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .name = LP8788_ALM_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .flags = IORESOURCE_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static const struct mfd_cell lp8788_devs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* 4 bucks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) MFD_DEV_WITH_ID(BUCK, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) MFD_DEV_WITH_ID(BUCK, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) MFD_DEV_WITH_ID(BUCK, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) MFD_DEV_WITH_ID(BUCK, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* 12 digital ldos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) MFD_DEV_WITH_ID(DLDO, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) MFD_DEV_WITH_ID(DLDO, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) MFD_DEV_WITH_ID(DLDO, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) MFD_DEV_WITH_ID(DLDO, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) MFD_DEV_WITH_ID(DLDO, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) MFD_DEV_WITH_ID(DLDO, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) MFD_DEV_WITH_ID(DLDO, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) MFD_DEV_WITH_ID(DLDO, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) MFD_DEV_WITH_ID(DLDO, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) MFD_DEV_WITH_ID(DLDO, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) MFD_DEV_WITH_ID(DLDO, 11),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) MFD_DEV_WITH_ID(DLDO, 12),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* 10 analog ldos */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) MFD_DEV_WITH_ID(ALDO, 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) MFD_DEV_WITH_ID(ALDO, 2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) MFD_DEV_WITH_ID(ALDO, 3),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) MFD_DEV_WITH_ID(ALDO, 4),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) MFD_DEV_WITH_ID(ALDO, 5),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) MFD_DEV_WITH_ID(ALDO, 6),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) MFD_DEV_WITH_ID(ALDO, 7),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) MFD_DEV_WITH_ID(ALDO, 8),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) MFD_DEV_WITH_ID(ALDO, 9),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MFD_DEV_WITH_ID(ALDO, 10),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) /* ADC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) MFD_DEV_SIMPLE(ADC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* battery charger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) MFD_DEV_WITH_RESOURCE(CHARGER, chg_irqs, ARRAY_SIZE(chg_irqs)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* rtc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) MFD_DEV_WITH_RESOURCE(RTC, rtc_irqs, ARRAY_SIZE(rtc_irqs)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /* backlight */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) MFD_DEV_SIMPLE(BACKLIGHT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /* current sink for vibrator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) MFD_DEV_SIMPLE(VIBRATOR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* current sink for keypad LED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) MFD_DEV_SIMPLE(KEYLED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int lp8788_read_byte(struct lp8788 *lp, u8 reg, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) ret = regmap_read(lp->regmap, reg, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) *data = (u8)val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) EXPORT_SYMBOL_GPL(lp8788_read_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) int lp8788_read_multi_bytes(struct lp8788 *lp, u8 reg, u8 *data, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return regmap_bulk_read(lp->regmap, reg, data, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) EXPORT_SYMBOL_GPL(lp8788_read_multi_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int lp8788_write_byte(struct lp8788 *lp, u8 reg, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return regmap_write(lp->regmap, reg, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) EXPORT_SYMBOL_GPL(lp8788_write_byte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) int lp8788_update_bits(struct lp8788 *lp, u8 reg, u8 mask, u8 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return regmap_update_bits(lp->regmap, reg, mask, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) EXPORT_SYMBOL_GPL(lp8788_update_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static int lp8788_platform_init(struct lp8788 *lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct lp8788_platform_data *pdata = lp->pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return (pdata && pdata->init_func) ? pdata->init_func(lp) : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static const struct regmap_config lp8788_regmap_config = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) .reg_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) .val_bits = 8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) .max_register = MAX_LP8788_REGISTERS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct lp8788 *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct lp8788_platform_data *pdata = dev_get_platdata(&cl->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) lp = devm_kzalloc(&cl->dev, sizeof(struct lp8788), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (!lp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) lp->regmap = devm_regmap_init_i2c(cl, &lp8788_regmap_config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (IS_ERR(lp->regmap)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) ret = PTR_ERR(lp->regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) dev_err(&cl->dev, "regmap init i2c err: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) lp->pdata = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) lp->dev = &cl->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) i2c_set_clientdata(cl, lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ret = lp8788_platform_init(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) ret = lp8788_irq_init(lp, cl->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return mfd_add_devices(lp->dev, -1, lp8788_devs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int lp8788_remove(struct i2c_client *cl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct lp8788 *lp = i2c_get_clientdata(cl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) mfd_remove_devices(lp->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) lp8788_irq_exit(lp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) static const struct i2c_device_id lp8788_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) {"lp8788", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) MODULE_DEVICE_TABLE(i2c, lp8788_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static struct i2c_driver lp8788_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .name = "lp8788",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) .probe = lp8788_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) .remove = lp8788_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) .id_table = lp8788_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) static int __init lp8788_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return i2c_add_driver(&lp8788_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) subsys_initcall(lp8788_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static void __exit lp8788_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) i2c_del_driver(&lp8788_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) module_exit(lp8788_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) MODULE_DESCRIPTION("TI LP8788 MFD Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) MODULE_AUTHOR("Milo Kim");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) MODULE_LICENSE("GPL");