Message ID | 539b8756120ab3558c906f7457e65f94dbe37425.1490608293.git.stwiss.opensource@diasemi.com (mailing list archive) |
---|---|
State | Not Applicable, archived |
Headers | show |
Hi Steve, [auto build test WARNING on ljones-mfd/for-mfd-next] [also build test WARNING on v4.11-rc4 next-20170327] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Steve-Twiss/Documentation-devicetree-watchdog-da9062-61-watchdog-timer-binding/20170327-215359 base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next config: x86_64-randconfig-x009-201713 (attached as .config) compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All warnings (new ones prefixed by >>): drivers//mfd/da9062-core.c: In function 'da9062_i2c_probe': >> drivers//mfd/da9062-core.c:845:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] chip->chip_type = (int)match->data; ^ vim +845 drivers//mfd/da9062-core.c 829 unsigned int irq_base; 830 const struct mfd_cell *cell; 831 const struct regmap_irq_chip *irq_chip; 832 const struct regmap_config *config; 833 int cell_num; 834 int ret; 835 836 chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); 837 if (!chip) 838 return -ENOMEM; 839 840 if (i2c->dev.of_node) { 841 match = of_match_node(da9062_dt_ids, i2c->dev.of_node); 842 if (!match) 843 return -EINVAL; 844 > 845 chip->chip_type = (int)match->data; 846 } else { 847 chip->chip_type = id->driver_data; 848 } 849 850 i2c_set_clientdata(i2c, chip); 851 chip->dev = &i2c->dev; 852 853 if (!i2c->irq) { --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Mon, 27 Mar 2017, kbuild test robot wrote: > Hi Steve, > > [auto build test WARNING on ljones-mfd/for-mfd-next] > [also build test WARNING on v4.11-rc4 next-20170327] > [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] > > url: https://github.com/0day-ci/linux/commits/Steve-Twiss/Documentation-devicetree-watchdog-da9062-61-watchdog-timer-binding/20170327-215359 > base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next > config: x86_64-randconfig-x009-201713 (attached as .config) > compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 > reproduce: > # save the attached .config to linux build tree > make ARCH=x86_64 > > All warnings (new ones prefixed by >>): > > drivers//mfd/da9062-core.c: In function 'da9062_i2c_probe': > >> drivers//mfd/da9062-core.c:845:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] > chip->chip_type = (int)match->data; > ^ Please use longs or enums. > vim +845 drivers//mfd/da9062-core.c > > 829 unsigned int irq_base; > 830 const struct mfd_cell *cell; > 831 const struct regmap_irq_chip *irq_chip; > 832 const struct regmap_config *config; > 833 int cell_num; > 834 int ret; > 835 > 836 chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); > 837 if (!chip) > 838 return -ENOMEM; > 839 > 840 if (i2c->dev.of_node) { > 841 match = of_match_node(da9062_dt_ids, i2c->dev.of_node); > 842 if (!match) > 843 return -EINVAL; > 844 > > 845 chip->chip_type = (int)match->data; > 846 } else { > 847 chip->chip_type = id->driver_data; > 848 } > 849 > 850 i2c_set_clientdata(i2c, chip); > 851 chip->dev = &i2c->dev; > 852 > 853 if (!i2c->irq) { > > --- > 0-DAY kernel test infrastructure Open Source Technology Center > https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi Lee, On Tue, Mar 28, 2017 at 10:21 AM, Lee Jones <lee.jones@linaro.org> wrote: >> [auto build test WARNING on ljones-mfd/for-mfd-next] >> [also build test WARNING on v4.11-rc4 next-20170327] >> [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] >> >> url: https://github.com/0day-ci/linux/commits/Steve-Twiss/Documentation-devicetree-watchdog-da9062-61-watchdog-timer-binding/20170327-215359 >> base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next >> config: x86_64-randconfig-x009-201713 (attached as .config) >> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 >> reproduce: >> # save the attached .config to linux build tree >> make ARCH=x86_64 >> >> All warnings (new ones prefixed by >>): >> >> drivers//mfd/da9062-core.c: In function 'da9062_i2c_probe': >> >> drivers//mfd/da9062-core.c:845:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] >> chip->chip_type = (int)match->data; >> ^ > > Please use longs or enums. Enums would still give a warning on 64-bit. The simple fix is change the cast from (int) to (uintptr_t). Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On 28 March 2017 09:37, Geert Uytterhoeven wrote: > Subject: Re: [PATCH V6 4/7] mfd: da9061: MFD core support > > Hi Lee, > > On Tue, Mar 28, 2017 at 10:21 AM, Lee Jones <lee.jones@linaro.org> wrote: > >> [auto build test WARNING on ljones-mfd/for-mfd-next] > >> [also build test WARNING on v4.11-rc4 next-20170327] > >> base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next > >> config: x86_64-randconfig-x009-201713 (attached as .config) > >> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 > >> reproduce: > >> # save the attached .config to linux build tree > >> make ARCH=x86_64 > >> > >> All warnings (new ones prefixed by >>): > >> > >> drivers//mfd/da9062-core.c: In function 'da9062_i2c_probe': > >> >> drivers//mfd/da9062-core.c:845:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] > >> chip->chip_type = (int)match->data; > >> ^ > > > > Please use longs or enums. > > Enums would still give a warning on 64-bit. > The simple fix is change the cast from (int) to (uintptr_t). Hi Lee and Geert, How about this? Fix by redefining the enum chip_type to be an int. Then, just use substitution: #define COMPAT_TYPE_DA9061 1 #define COMPAT_TYPE_DA9062 2 That would be simple. Are there any reasons this would not be acceptable? Regards, Steve
Hi Steve, On Tue, Mar 28, 2017 at 12:42 PM, Steve Twiss <stwiss.opensource@diasemi.com> wrote: > On 28 March 2017 09:37, Geert Uytterhoeven wrote: >> Subject: Re: [PATCH V6 4/7] mfd: da9061: MFD core support >> On Tue, Mar 28, 2017 at 10:21 AM, Lee Jones <lee.jones@linaro.org> wrote: >> >> [auto build test WARNING on ljones-mfd/for-mfd-next] >> >> [also build test WARNING on v4.11-rc4 next-20170327] >> >> base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next >> >> config: x86_64-randconfig-x009-201713 (attached as .config) >> >> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 >> >> reproduce: >> >> # save the attached .config to linux build tree >> >> make ARCH=x86_64 >> >> >> >> All warnings (new ones prefixed by >>): >> >> >> >> drivers//mfd/da9062-core.c: In function 'da9062_i2c_probe': >> >> >> drivers//mfd/da9062-core.c:845:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] >> >> chip->chip_type = (int)match->data; >> >> ^ >> > >> > Please use longs or enums. >> >> Enums would still give a warning on 64-bit. >> The simple fix is change the cast from (int) to (uintptr_t). > > Hi Lee and Geert, > > How about this? Fix by redefining the enum chip_type to be an int. > Then, just use substitution: > #define COMPAT_TYPE_DA9061 1 > #define COMPAT_TYPE_DA9062 2 > > That would be simple. > Are there any reasons this would not be acceptable? I don't see how that can help. The warning is caused by casting the "void *" (which is either 32-bit or 64-bit) in of_device_if.data to an integer or enum (which is always 32-bit). The right fix is to cast it to uintptr_t intead of int, like other drivers do. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On 28 March 2017 11:51, Geert Uytterhoeven wrote: > Hi Steve, > > On Tue, Mar 28, 2017 at 12:42 PM, Steve Twiss wrote: > > On 28 March 2017 09:37, Geert Uytterhoeven wrote: > >> Subject: Re: [PATCH V6 4/7] mfd: da9061: MFD core support > >> On Tue, Mar 28, 2017 at 10:21 AM, Lee Jones <lee.jones@linaro.org> wrote: > >> >> [auto build test WARNING on ljones-mfd/for-mfd-next] > >> >> [also build test WARNING on v4.11-rc4 next-20170327] > >> >> base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next > >> >> config: x86_64-randconfig-x009-201713 (attached as .config) > >> >> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 > >> >> reproduce: > >> >> # save the attached .config to linux build tree > >> >> make ARCH=x86_64 > >> >> > >> >> All warnings (new ones prefixed by >>): > >> >> > >> >> drivers//mfd/da9062-core.c: In function 'da9062_i2c_probe': > >> >> >> drivers//mfd/da9062-core.c:845:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] > >> >> chip->chip_type = (int)match->data; > >> >> ^ > >> > > >> > Please use longs or enums. > >> > >> Enums would still give a warning on 64-bit. > >> The simple fix is change the cast from (int) to (uintptr_t). > > > > Hi Lee and Geert, > > > > How about this? Fix by redefining the enum chip_type to be an int. > > Then, just use substitution: > > #define COMPAT_TYPE_DA9061 1 > > #define COMPAT_TYPE_DA9062 2 > > > > That would be simple. > > Are there any reasons this would not be acceptable? > > I don't see how that can help. > The warning is caused by casting the "void *" (which is either 32-bit or > 64-bit) in of_device_if.data to an integer or enum (which is always 32-bit). > > The right fix is to cast it to uintptr_t intead of int, like other drivers do. Thanks Geert, Um. Of course. Thanks, and my apologies. It would have helped if I had compile tested the right file :( I'll follow the convention and cast (uintptr_t). Thanks, Steve
On Tue, 28 Mar 2017, Geert Uytterhoeven wrote: > Hi Steve, > > On Tue, Mar 28, 2017 at 12:42 PM, Steve Twiss > <stwiss.opensource@diasemi.com> wrote: > > On 28 March 2017 09:37, Geert Uytterhoeven wrote: > >> Subject: Re: [PATCH V6 4/7] mfd: da9061: MFD core support > >> On Tue, Mar 28, 2017 at 10:21 AM, Lee Jones <lee.jones@linaro.org> wrote: > >> >> [auto build test WARNING on ljones-mfd/for-mfd-next] > >> >> [also build test WARNING on v4.11-rc4 next-20170327] > >> >> base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next > >> >> config: x86_64-randconfig-x009-201713 (attached as .config) > >> >> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 > >> >> reproduce: > >> >> # save the attached .config to linux build tree > >> >> make ARCH=x86_64 > >> >> > >> >> All warnings (new ones prefixed by >>): > >> >> > >> >> drivers//mfd/da9062-core.c: In function 'da9062_i2c_probe': > >> >> >> drivers//mfd/da9062-core.c:845:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] > >> >> chip->chip_type = (int)match->data; > >> >> ^ > >> > > >> > Please use longs or enums. > >> > >> Enums would still give a warning on 64-bit. > >> The simple fix is change the cast from (int) to (uintptr_t). > > > > Hi Lee and Geert, > > > > How about this? Fix by redefining the enum chip_type to be an int. > > Then, just use substitution: > > #define COMPAT_TYPE_DA9061 1 > > #define COMPAT_TYPE_DA9062 2 > > > > That would be simple. > > Are there any reasons this would not be acceptable? > > I don't see how that can help. > The warning is caused by casting the "void *" (which is either 32-bit or > 64-bit) in of_device_if.data to an integer or enum (which is always 32-bit). > > The right fix is to cast it to uintptr_t intead of int, like other drivers do. That's a hack though, isn't it? chip->chip_type is not of type uintptr_t, so all you're doing here is making the compiler happy. I see people using (int)(uintptr_t), which I guess keeps the compiler happy in the first instance and actually culminates in a correct cast to the right type. So how about something like (enum da9062_compatible_types)(long)?
Hi Lee, On Wed, Mar 29, 2017 at 10:30 AM, Lee Jones <lee.jones@linaro.org> wrote: > On Tue, 28 Mar 2017, Geert Uytterhoeven wrote: >> On Tue, Mar 28, 2017 at 12:42 PM, Steve Twiss >> <stwiss.opensource@diasemi.com> wrote: >> > On 28 March 2017 09:37, Geert Uytterhoeven wrote: >> >> Subject: Re: [PATCH V6 4/7] mfd: da9061: MFD core support >> >> On Tue, Mar 28, 2017 at 10:21 AM, Lee Jones <lee.jones@linaro.org> wrote: >> >> >> [auto build test WARNING on ljones-mfd/for-mfd-next] >> >> >> [also build test WARNING on v4.11-rc4 next-20170327] >> >> >> base: https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next >> >> >> config: x86_64-randconfig-x009-201713 (attached as .config) >> >> >> compiler: gcc-6 (Debian 6.2.0-3) 6.2.0 20160901 >> >> >> reproduce: >> >> >> # save the attached .config to linux build tree >> >> >> make ARCH=x86_64 >> >> >> >> >> >> All warnings (new ones prefixed by >>): >> >> >> >> >> >> drivers//mfd/da9062-core.c: In function 'da9062_i2c_probe': >> >> >> >> drivers//mfd/da9062-core.c:845:21: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] >> >> >> chip->chip_type = (int)match->data; >> >> >> ^ >> >> > >> >> > Please use longs or enums. >> >> >> >> Enums would still give a warning on 64-bit. >> >> The simple fix is change the cast from (int) to (uintptr_t). >> > >> > Hi Lee and Geert, >> > >> > How about this? Fix by redefining the enum chip_type to be an int. >> > Then, just use substitution: >> > #define COMPAT_TYPE_DA9061 1 >> > #define COMPAT_TYPE_DA9062 2 >> > >> > That would be simple. >> > Are there any reasons this would not be acceptable? >> >> I don't see how that can help. >> The warning is caused by casting the "void *" (which is either 32-bit or >> 64-bit) in of_device_if.data to an integer or enum (which is always 32-bit). >> >> The right fix is to cast it to uintptr_t intead of int, like other drivers do. > > That's a hack though, isn't it? chip->chip_type is not of type > uintptr_t, so all you're doing here is making the compiler happy. It's a hack, in the sense that using casts is usually a hack :-) (I would love for C to have casts you can easily grep for, like C++ has) In this case, it's not really a hack, as the void * is intended to store arbitrary data, both pointers and integers. > I see people using (int)(uintptr_t), which I guess keeps the > compiler happy in the first instance and actually culminates in a > correct cast to the right type. The cast to int isn't really needed. > So how about something like (enum da9062_compatible_types)(long)? "uintptr_t" is the proper C standard type for conversion between pointers and integers. The cast to the enum isn't really needed, so I'd remove it (the less number of casts, the better!). Long is the hack that works on ILP32 and LP64 platforms only ;-) Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 55ecdfb..29cc11a 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -263,13 +263,14 @@ config MFD_DA9055 called "da9055" config MFD_DA9062 - tristate "Dialog Semiconductor DA9062 PMIC Support" + tristate "Dialog Semiconductor DA9062/61 PMIC Support" select MFD_CORE select REGMAP_I2C select REGMAP_IRQ depends on I2C help - Say yes here for support for the Dialog Semiconductor DA9062 PMIC. + Say yes here for support for the Dialog Semiconductor DA9061 and + DA9062 PMICs. This includes the I2C driver and core APIs. Additional drivers must be enabled in order to use the functionality of the device. diff --git a/drivers/mfd/da9062-core.c b/drivers/mfd/da9062-core.c index 8f873866..9310eaf 100644 --- a/drivers/mfd/da9062-core.c +++ b/drivers/mfd/da9062-core.c @@ -1,6 +1,6 @@ /* - * Core, IRQ and I2C device driver for DA9062 PMIC - * Copyright (C) 2015 Dialog Semiconductor Ltd. + * Core, IRQ and I2C device driver for DA9061 and DA9062 PMICs + * Copyright (C) 2015-2017 Dialog Semiconductor * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -30,6 +30,70 @@ #define DA9062_REG_EVENT_B_OFFSET 1 #define DA9062_REG_EVENT_C_OFFSET 2 +static struct regmap_irq da9061_irqs[] = { + /* EVENT A */ + [DA9061_IRQ_ONKEY] = { + .reg_offset = DA9062_REG_EVENT_A_OFFSET, + .mask = DA9062AA_M_NONKEY_MASK, + }, + [DA9061_IRQ_WDG_WARN] = { + .reg_offset = DA9062_REG_EVENT_A_OFFSET, + .mask = DA9062AA_M_WDG_WARN_MASK, + }, + [DA9061_IRQ_SEQ_RDY] = { + .reg_offset = DA9062_REG_EVENT_A_OFFSET, + .mask = DA9062AA_M_SEQ_RDY_MASK, + }, + /* EVENT B */ + [DA9061_IRQ_TEMP] = { + .reg_offset = DA9062_REG_EVENT_B_OFFSET, + .mask = DA9062AA_M_TEMP_MASK, + }, + [DA9061_IRQ_LDO_LIM] = { + .reg_offset = DA9062_REG_EVENT_B_OFFSET, + .mask = DA9062AA_M_LDO_LIM_MASK, + }, + [DA9061_IRQ_DVC_RDY] = { + .reg_offset = DA9062_REG_EVENT_B_OFFSET, + .mask = DA9062AA_M_DVC_RDY_MASK, + }, + [DA9061_IRQ_VDD_WARN] = { + .reg_offset = DA9062_REG_EVENT_B_OFFSET, + .mask = DA9062AA_M_VDD_WARN_MASK, + }, + /* EVENT C */ + [DA9061_IRQ_GPI0] = { + .reg_offset = DA9062_REG_EVENT_C_OFFSET, + .mask = DA9062AA_M_GPI0_MASK, + }, + [DA9061_IRQ_GPI1] = { + .reg_offset = DA9062_REG_EVENT_C_OFFSET, + .mask = DA9062AA_M_GPI1_MASK, + }, + [DA9061_IRQ_GPI2] = { + .reg_offset = DA9062_REG_EVENT_C_OFFSET, + .mask = DA9062AA_M_GPI2_MASK, + }, + [DA9061_IRQ_GPI3] = { + .reg_offset = DA9062_REG_EVENT_C_OFFSET, + .mask = DA9062AA_M_GPI3_MASK, + }, + [DA9061_IRQ_GPI4] = { + .reg_offset = DA9062_REG_EVENT_C_OFFSET, + .mask = DA9062AA_M_GPI4_MASK, + }, +}; + +static struct regmap_irq_chip da9061_irq_chip = { + .name = "da9061-irq", + .irqs = da9061_irqs, + .num_irqs = DA9061_NUM_IRQ, + .num_regs = 3, + .status_base = DA9062AA_EVENT_A, + .mask_base = DA9062AA_IRQ_MASK_A, + .ack_base = DA9062AA_EVENT_A, +}; + static struct regmap_irq da9062_irqs[] = { /* EVENT A */ [DA9062_IRQ_ONKEY] = { @@ -102,6 +166,57 @@ .ack_base = DA9062AA_EVENT_A, }; +static struct resource da9061_core_resources[] = { + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_VDD_WARN, "VDD_WARN"), +}; + +static struct resource da9061_regulators_resources[] = { + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_LDO_LIM, "LDO_LIM"), +}; + +static struct resource da9061_thermal_resources[] = { + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_TEMP, "THERMAL"), +}; + +static struct resource da9061_wdt_resources[] = { + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_WDG_WARN, "WD_WARN"), +}; + +static struct resource da9061_onkey_resources[] = { + DEFINE_RES_IRQ_NAMED(DA9061_IRQ_ONKEY, "ONKEY"), +}; + +static const struct mfd_cell da9061_devs[] = { + { + .name = "da9061-core", + .num_resources = ARRAY_SIZE(da9061_core_resources), + .resources = da9061_core_resources, + }, + { + .name = "da9062-regulators", + .num_resources = ARRAY_SIZE(da9061_regulators_resources), + .resources = da9061_regulators_resources, + }, + { + .name = "da9061-watchdog", + .num_resources = ARRAY_SIZE(da9061_wdt_resources), + .resources = da9061_wdt_resources, + .of_compatible = "dlg,da9061-watchdog", + }, + { + .name = "da9061-thermal", + .num_resources = ARRAY_SIZE(da9061_thermal_resources), + .resources = da9061_thermal_resources, + .of_compatible = "dlg,da9061-thermal", + }, + { + .name = "da9061-onkey", + .num_resources = ARRAY_SIZE(da9061_onkey_resources), + .resources = da9061_onkey_resources, + .of_compatible = "dlg,da9061-onkey", + }, +}; + static struct resource da9062_core_resources[] = { DEFINE_RES_NAMED(DA9062_IRQ_VDD_WARN, 1, "VDD_WARN", IORESOURCE_IRQ), }; @@ -200,7 +315,8 @@ static int da9062_clear_fault_log(struct da9062 *chip) static int da9062_get_device_type(struct da9062 *chip) { - int device_id, variant_id, variant_mrc; + int device_id, variant_id, variant_mrc, variant_vrc; + char *type; int ret; ret = regmap_read(chip->regmap, DA9062AA_DEVICE_ID, &device_id); @@ -219,9 +335,23 @@ static int da9062_get_device_type(struct da9062 *chip) return -EIO; } + variant_vrc = (variant_id & DA9062AA_VRC_MASK) >> DA9062AA_VRC_SHIFT; + + switch (variant_vrc) { + case DA9062_PMIC_VARIANT_VRC_DA9061: + type = "DA9061"; + break; + case DA9062_PMIC_VARIANT_VRC_DA9062: + type = "DA9062"; + break; + default: + type = "Unknown"; + break; + } + dev_info(chip->dev, - "Device detected (device-ID: 0x%02X, var-ID: 0x%02X)\n", - device_id, variant_id); + "Device detected (device-ID: 0x%02X, var-ID: 0x%02X, %s)\n", + device_id, variant_id, type); variant_mrc = (variant_id & DA9062AA_MRC_MASK) >> DA9062AA_MRC_SHIFT; @@ -234,6 +364,234 @@ static int da9062_get_device_type(struct da9062 *chip) return ret; } +static const struct regmap_range da9061_aa_readable_ranges[] = { + { + .range_min = DA9062AA_PAGE_CON, + .range_max = DA9062AA_STATUS_B, + }, { + .range_min = DA9062AA_STATUS_D, + .range_max = DA9062AA_EVENT_C, + }, { + .range_min = DA9062AA_IRQ_MASK_A, + .range_max = DA9062AA_IRQ_MASK_C, + }, { + .range_min = DA9062AA_CONTROL_A, + .range_max = DA9062AA_GPIO_4, + }, { + .range_min = DA9062AA_GPIO_WKUP_MODE, + .range_max = DA9062AA_GPIO_OUT3_4, + }, { + .range_min = DA9062AA_BUCK1_CONT, + .range_max = DA9062AA_BUCK4_CONT, + }, { + .range_min = DA9062AA_BUCK3_CONT, + .range_max = DA9062AA_BUCK3_CONT, + }, { + .range_min = DA9062AA_LDO1_CONT, + .range_max = DA9062AA_LDO4_CONT, + }, { + .range_min = DA9062AA_DVC_1, + .range_max = DA9062AA_DVC_1, + }, { + .range_min = DA9062AA_SEQ, + .range_max = DA9062AA_ID_4_3, + }, { + .range_min = DA9062AA_ID_12_11, + .range_max = DA9062AA_ID_16_15, + }, { + .range_min = DA9062AA_ID_22_21, + .range_max = DA9062AA_ID_32_31, + }, { + .range_min = DA9062AA_SEQ_A, + .range_max = DA9062AA_WAIT, + }, { + .range_min = DA9062AA_RESET, + .range_max = DA9062AA_BUCK_ILIM_C, + }, { + .range_min = DA9062AA_BUCK1_CFG, + .range_max = DA9062AA_BUCK3_CFG, + }, { + .range_min = DA9062AA_VBUCK1_A, + .range_max = DA9062AA_VBUCK4_A, + }, { + .range_min = DA9062AA_VBUCK3_A, + .range_max = DA9062AA_VBUCK3_A, + }, { + .range_min = DA9062AA_VLDO1_A, + .range_max = DA9062AA_VLDO4_A, + }, { + .range_min = DA9062AA_VBUCK1_B, + .range_max = DA9062AA_VBUCK4_B, + }, { + .range_min = DA9062AA_VBUCK3_B, + .range_max = DA9062AA_VBUCK3_B, + }, { + .range_min = DA9062AA_VLDO1_B, + .range_max = DA9062AA_VLDO4_B, + }, { + .range_min = DA9062AA_BBAT_CONT, + .range_max = DA9062AA_BBAT_CONT, + }, { + .range_min = DA9062AA_INTERFACE, + .range_max = DA9062AA_CONFIG_E, + }, { + .range_min = DA9062AA_CONFIG_G, + .range_max = DA9062AA_CONFIG_K, + }, { + .range_min = DA9062AA_CONFIG_M, + .range_max = DA9062AA_CONFIG_M, + }, { + .range_min = DA9062AA_GP_ID_0, + .range_max = DA9062AA_GP_ID_19, + }, { + .range_min = DA9062AA_DEVICE_ID, + .range_max = DA9062AA_CONFIG_ID, + }, +}; + +static const struct regmap_range da9061_aa_writeable_ranges[] = { + { + .range_min = DA9062AA_PAGE_CON, + .range_max = DA9062AA_PAGE_CON, + }, { + .range_min = DA9062AA_FAULT_LOG, + .range_max = DA9062AA_EVENT_C, + }, { + .range_min = DA9062AA_IRQ_MASK_A, + .range_max = DA9062AA_IRQ_MASK_C, + }, { + .range_min = DA9062AA_CONTROL_A, + .range_max = DA9062AA_GPIO_4, + }, { + .range_min = DA9062AA_GPIO_WKUP_MODE, + .range_max = DA9062AA_GPIO_OUT3_4, + }, { + .range_min = DA9062AA_BUCK1_CONT, + .range_max = DA9062AA_BUCK4_CONT, + }, { + .range_min = DA9062AA_BUCK3_CONT, + .range_max = DA9062AA_BUCK3_CONT, + }, { + .range_min = DA9062AA_LDO1_CONT, + .range_max = DA9062AA_LDO4_CONT, + }, { + .range_min = DA9062AA_DVC_1, + .range_max = DA9062AA_DVC_1, + }, { + .range_min = DA9062AA_SEQ, + .range_max = DA9062AA_ID_4_3, + }, { + .range_min = DA9062AA_ID_12_11, + .range_max = DA9062AA_ID_16_15, + }, { + .range_min = DA9062AA_ID_22_21, + .range_max = DA9062AA_ID_32_31, + }, { + .range_min = DA9062AA_SEQ_A, + .range_max = DA9062AA_WAIT, + }, { + .range_min = DA9062AA_RESET, + .range_max = DA9062AA_BUCK_ILIM_C, + }, { + .range_min = DA9062AA_BUCK1_CFG, + .range_max = DA9062AA_BUCK3_CFG, + }, { + .range_min = DA9062AA_VBUCK1_A, + .range_max = DA9062AA_VBUCK4_A, + }, { + .range_min = DA9062AA_VBUCK3_A, + .range_max = DA9062AA_VBUCK3_A, + }, { + .range_min = DA9062AA_VLDO1_A, + .range_max = DA9062AA_VLDO4_A, + }, { + .range_min = DA9062AA_VBUCK1_B, + .range_max = DA9062AA_VBUCK4_B, + }, { + .range_min = DA9062AA_VBUCK3_B, + .range_max = DA9062AA_VBUCK3_B, + }, { + .range_min = DA9062AA_VLDO1_B, + .range_max = DA9062AA_VLDO4_B, + }, { + .range_min = DA9062AA_BBAT_CONT, + .range_max = DA9062AA_BBAT_CONT, + }, { + .range_min = DA9062AA_GP_ID_0, + .range_max = DA9062AA_GP_ID_19, + }, +}; + +static const struct regmap_range da9061_aa_volatile_ranges[] = { + { + .range_min = DA9062AA_PAGE_CON, + .range_max = DA9062AA_STATUS_B, + }, { + .range_min = DA9062AA_STATUS_D, + .range_max = DA9062AA_EVENT_C, + }, { + .range_min = DA9062AA_CONTROL_A, + .range_max = DA9062AA_CONTROL_B, + }, { + .range_min = DA9062AA_CONTROL_E, + .range_max = DA9062AA_CONTROL_F, + }, { + .range_min = DA9062AA_BUCK1_CONT, + .range_max = DA9062AA_BUCK4_CONT, + }, { + .range_min = DA9062AA_BUCK3_CONT, + .range_max = DA9062AA_BUCK3_CONT, + }, { + .range_min = DA9062AA_LDO1_CONT, + .range_max = DA9062AA_LDO4_CONT, + }, { + .range_min = DA9062AA_DVC_1, + .range_max = DA9062AA_DVC_1, + }, { + .range_min = DA9062AA_SEQ, + .range_max = DA9062AA_SEQ, + }, +}; + +static const struct regmap_access_table da9061_aa_readable_table = { + .yes_ranges = da9061_aa_readable_ranges, + .n_yes_ranges = ARRAY_SIZE(da9061_aa_readable_ranges), +}; + +static const struct regmap_access_table da9061_aa_writeable_table = { + .yes_ranges = da9061_aa_writeable_ranges, + .n_yes_ranges = ARRAY_SIZE(da9061_aa_writeable_ranges), +}; + +static const struct regmap_access_table da9061_aa_volatile_table = { + .yes_ranges = da9061_aa_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(da9061_aa_volatile_ranges), +}; + +static const struct regmap_range_cfg da9061_range_cfg[] = { + { + .range_min = DA9062AA_PAGE_CON, + .range_max = DA9062AA_CONFIG_ID, + .selector_reg = DA9062AA_PAGE_CON, + .selector_mask = 1 << DA9062_I2C_PAGE_SEL_SHIFT, + .selector_shift = DA9062_I2C_PAGE_SEL_SHIFT, + .window_start = 0, + .window_len = 256, + } +}; + +static struct regmap_config da9061_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .ranges = da9061_range_cfg, + .num_ranges = ARRAY_SIZE(da9061_range_cfg), + .max_register = DA9062AA_CONFIG_ID, + .cache_type = REGCACHE_RBTREE, + .rd_table = &da9061_aa_readable_table, + .wr_table = &da9061_aa_writeable_table, + .volatile_table = &da9061_aa_volatile_table, +}; + static const struct regmap_range da9062_aa_readable_ranges[] = { { .range_min = DA9062AA_PAGE_CON, @@ -456,17 +814,39 @@ static int da9062_get_device_type(struct da9062 *chip) .volatile_table = &da9062_aa_volatile_table, }; +static const struct of_device_id da9062_dt_ids[] = { + { .compatible = "dlg,da9061", .data = (void *)COMPAT_TYPE_DA9061, }, + { .compatible = "dlg,da9062", .data = (void *)COMPAT_TYPE_DA9062, }, + { } +}; +MODULE_DEVICE_TABLE(of, da9062_dt_ids); + static int da9062_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct da9062 *chip; + const struct of_device_id *match; unsigned int irq_base; + const struct mfd_cell *cell; + const struct regmap_irq_chip *irq_chip; + const struct regmap_config *config; + int cell_num; int ret; chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL); if (!chip) return -ENOMEM; + if (i2c->dev.of_node) { + match = of_match_node(da9062_dt_ids, i2c->dev.of_node); + if (!match) + return -EINVAL; + + chip->chip_type = (int)match->data; + } else { + chip->chip_type = id->driver_data; + } + i2c_set_clientdata(i2c, chip); chip->dev = &i2c->dev; @@ -475,7 +855,25 @@ static int da9062_i2c_probe(struct i2c_client *i2c, return -EINVAL; } - chip->regmap = devm_regmap_init_i2c(i2c, &da9062_regmap_config); + switch (chip->chip_type) { + case(COMPAT_TYPE_DA9061): + cell = da9061_devs; + cell_num = ARRAY_SIZE(da9061_devs); + irq_chip = &da9061_irq_chip; + config = &da9061_regmap_config; + break; + case(COMPAT_TYPE_DA9062): + cell = da9062_devs; + cell_num = ARRAY_SIZE(da9062_devs); + irq_chip = &da9062_irq_chip; + config = &da9062_regmap_config; + break; + default: + dev_err(chip->dev, "Unrecognised chip type\n"); + return -ENODEV; + } + + chip->regmap = devm_regmap_init_i2c(i2c, config); if (IS_ERR(chip->regmap)) { ret = PTR_ERR(chip->regmap); dev_err(chip->dev, "Failed to allocate register map: %d\n", @@ -493,7 +891,7 @@ static int da9062_i2c_probe(struct i2c_client *i2c, ret = regmap_add_irq_chip(chip->regmap, i2c->irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, - -1, &da9062_irq_chip, + -1, irq_chip, &chip->regmap_irq); if (ret) { dev_err(chip->dev, "Failed to request IRQ %d: %d\n", @@ -503,8 +901,8 @@ static int da9062_i2c_probe(struct i2c_client *i2c, irq_base = regmap_irq_chip_get_base(chip->regmap_irq); - ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, da9062_devs, - ARRAY_SIZE(da9062_devs), NULL, irq_base, + ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, cell, + cell_num, NULL, irq_base, NULL); if (ret) { dev_err(chip->dev, "Cannot register child devices\n"); @@ -526,17 +924,12 @@ static int da9062_i2c_remove(struct i2c_client *i2c) } static const struct i2c_device_id da9062_i2c_id[] = { - { "da9062", 0 }, + { "da9061", COMPAT_TYPE_DA9061 }, + { "da9062", COMPAT_TYPE_DA9062 }, { }, }; MODULE_DEVICE_TABLE(i2c, da9062_i2c_id); -static const struct of_device_id da9062_dt_ids[] = { - { .compatible = "dlg,da9062", }, - { } -}; -MODULE_DEVICE_TABLE(of, da9062_dt_ids); - static struct i2c_driver da9062_i2c_driver = { .driver = { .name = "da9062", @@ -549,6 +942,6 @@ static int da9062_i2c_remove(struct i2c_client *i2c) module_i2c_driver(da9062_i2c_driver); -MODULE_DESCRIPTION("Core device driver for Dialog DA9062"); +MODULE_DESCRIPTION("Core device driver for Dialog DA9061 and DA9062"); MODULE_AUTHOR("Steve Twiss <stwiss.opensource@diasemi.com>"); MODULE_LICENSE("GPL"); diff --git a/include/linux/mfd/da9062/core.h b/include/linux/mfd/da9062/core.h index 376ba84..74d33a0 100644 --- a/include/linux/mfd/da9062/core.h +++ b/include/linux/mfd/da9062/core.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Dialog Semiconductor Ltd. + * Copyright (C) 2015-2017 Dialog Semiconductor * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,7 +18,31 @@ #include <linux/interrupt.h> #include <linux/mfd/da9062/registers.h> -/* Interrupts */ +enum da9062_compatible_types { + COMPAT_TYPE_DA9061 = 1, + COMPAT_TYPE_DA9062, +}; + +enum da9061_irqs { + /* IRQ A */ + DA9061_IRQ_ONKEY, + DA9061_IRQ_WDG_WARN, + DA9061_IRQ_SEQ_RDY, + /* IRQ B*/ + DA9061_IRQ_TEMP, + DA9061_IRQ_LDO_LIM, + DA9061_IRQ_DVC_RDY, + DA9061_IRQ_VDD_WARN, + /* IRQ C */ + DA9061_IRQ_GPI0, + DA9061_IRQ_GPI1, + DA9061_IRQ_GPI2, + DA9061_IRQ_GPI3, + DA9061_IRQ_GPI4, + + DA9061_NUM_IRQ, +}; + enum da9062_irqs { /* IRQ A */ DA9062_IRQ_ONKEY, @@ -45,6 +69,7 @@ struct da9062 { struct device *dev; struct regmap *regmap; struct regmap_irq_chip_data *regmap_irq; + enum da9062_compatible_types chip_type; }; #endif /* __MFD_DA9062_CORE_H__ */ diff --git a/include/linux/mfd/da9062/registers.h b/include/linux/mfd/da9062/registers.h index 97790d1..18d576a 100644 --- a/include/linux/mfd/da9062/registers.h +++ b/include/linux/mfd/da9062/registers.h @@ -1,6 +1,5 @@ /* - * registers.h - REGISTERS H for DA9062 - * Copyright (C) 2015 Dialog Semiconductor Ltd. + * Copyright (C) 2015-2017 Dialog Semiconductor * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -18,6 +17,8 @@ #define DA9062_PMIC_DEVICE_ID 0x62 #define DA9062_PMIC_VARIANT_MRC_AA 0x01 +#define DA9062_PMIC_VARIANT_VRC_DA9061 0x01 +#define DA9062_PMIC_VARIANT_VRC_DA9062 0x02 #define DA9062_I2C_PAGE_SEL_SHIFT 1