.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * MFD core driver for Rockchip RK808/RK818 |
---|
3 | 4 | * |
---|
.. | .. |
---|
9 | 10 | * Copyright (C) 2016 PHYTEC Messtechnik GmbH |
---|
10 | 11 | * |
---|
11 | 12 | * Author: Wadim Egorov <w.egorov@phytec.de> |
---|
12 | | - * |
---|
13 | | - * This program is free software; you can redistribute it and/or modify it |
---|
14 | | - * under the terms and conditions of the GNU General Public License, |
---|
15 | | - * version 2, as published by the Free Software Foundation. |
---|
16 | | - * |
---|
17 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
---|
18 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
---|
19 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
---|
20 | | - * more details. |
---|
21 | 13 | */ |
---|
22 | 14 | |
---|
23 | 15 | #include <linux/i2c.h> |
---|
.. | .. |
---|
167 | 159 | .volatile_reg = rk817_is_volatile_reg, |
---|
168 | 160 | }; |
---|
169 | 161 | |
---|
170 | | -static struct resource rtc_resources[] = { |
---|
171 | | - { |
---|
172 | | - .start = RK808_IRQ_RTC_ALARM, |
---|
173 | | - .end = RK808_IRQ_RTC_ALARM, |
---|
174 | | - .flags = IORESOURCE_IRQ, |
---|
175 | | - } |
---|
| 162 | +static const struct resource rtc_resources[] = { |
---|
| 163 | + DEFINE_RES_IRQ(RK808_IRQ_RTC_ALARM), |
---|
176 | 164 | }; |
---|
177 | 165 | |
---|
178 | | -static struct resource rk816_rtc_resources[] = { |
---|
179 | | - { |
---|
180 | | - .start = RK816_IRQ_RTC_ALARM, |
---|
181 | | - .end = RK816_IRQ_RTC_ALARM, |
---|
182 | | - .flags = IORESOURCE_IRQ, |
---|
183 | | - } |
---|
| 166 | +static const struct resource rk816_rtc_resources[] = { |
---|
| 167 | + DEFINE_RES_IRQ(RK816_IRQ_RTC_ALARM), |
---|
184 | 168 | }; |
---|
185 | 169 | |
---|
186 | | -static struct resource rk817_rtc_resources[] = { |
---|
| 170 | +static const struct resource rk817_rtc_resources[] = { |
---|
187 | 171 | DEFINE_RES_IRQ(RK817_IRQ_RTC_ALARM), |
---|
188 | 172 | }; |
---|
189 | 173 | |
---|
190 | | -static struct resource rk805_key_resources[] = { |
---|
191 | | - { |
---|
192 | | - .start = RK805_IRQ_PWRON_FALL, |
---|
193 | | - .end = RK805_IRQ_PWRON_FALL, |
---|
194 | | - .flags = IORESOURCE_IRQ, |
---|
195 | | - }, |
---|
196 | | - { |
---|
197 | | - .start = RK805_IRQ_PWRON_RISE, |
---|
198 | | - .end = RK805_IRQ_PWRON_RISE, |
---|
199 | | - .flags = IORESOURCE_IRQ, |
---|
200 | | - } |
---|
| 174 | +static const struct resource rk805_key_resources[] = { |
---|
| 175 | + DEFINE_RES_IRQ(RK805_IRQ_PWRON_FALL), |
---|
| 176 | + DEFINE_RES_IRQ(RK805_IRQ_PWRON_RISE), |
---|
201 | 177 | }; |
---|
202 | 178 | |
---|
203 | | -static struct resource rk816_pwrkey_resources[] = { |
---|
204 | | - { |
---|
205 | | - .start = RK816_IRQ_PWRON_FALL, |
---|
206 | | - .end = RK816_IRQ_PWRON_FALL, |
---|
207 | | - .flags = IORESOURCE_IRQ, |
---|
208 | | - }, |
---|
209 | | - { |
---|
210 | | - .start = RK816_IRQ_PWRON_RISE, |
---|
211 | | - .end = RK816_IRQ_PWRON_RISE, |
---|
212 | | - .flags = IORESOURCE_IRQ, |
---|
213 | | - }, |
---|
| 179 | +static const struct resource rk816_pwrkey_resources[] = { |
---|
| 180 | + DEFINE_RES_IRQ(RK816_IRQ_PWRON_FALL), |
---|
| 181 | + DEFINE_RES_IRQ(RK816_IRQ_PWRON_RISE), |
---|
214 | 182 | }; |
---|
215 | 183 | |
---|
216 | | -static struct resource rk817_pwrkey_resources[] = { |
---|
| 184 | +static const struct resource rk817_pwrkey_resources[] = { |
---|
217 | 185 | DEFINE_RES_IRQ(RK817_IRQ_PWRON_FALL), |
---|
218 | 186 | DEFINE_RES_IRQ(RK817_IRQ_PWRON_RISE), |
---|
219 | 187 | }; |
---|
.. | .. |
---|
613 | 581 | REGMAP_IRQ_REG_LINE(23, 8) |
---|
614 | 582 | }; |
---|
615 | 583 | |
---|
616 | | -static struct regmap_irq_chip rk805_irq_chip = { |
---|
| 584 | +static const struct regmap_irq_chip rk805_irq_chip = { |
---|
617 | 585 | .name = "rk805", |
---|
618 | 586 | .irqs = rk805_irqs, |
---|
619 | 587 | .num_irqs = ARRAY_SIZE(rk805_irqs), |
---|
.. | .. |
---|
668 | 636 | }, |
---|
669 | 637 | }; |
---|
670 | 638 | |
---|
671 | | -static struct regmap_irq_chip rk816_irq_chip = { |
---|
| 639 | +static const struct regmap_irq_chip rk816_irq_chip = { |
---|
672 | 640 | .name = "rk816", |
---|
673 | 641 | .irqs = rk816_irqs, |
---|
674 | 642 | .num_irqs = ARRAY_SIZE(rk816_irqs), |
---|
.. | .. |
---|
680 | 648 | .init_ack_masked = true, |
---|
681 | 649 | }; |
---|
682 | 650 | |
---|
683 | | -static struct regmap_irq_chip rk816_battery_irq_chip = { |
---|
| 651 | +static const struct regmap_irq_chip rk816_battery_irq_chip = { |
---|
684 | 652 | .name = "rk816_battery", |
---|
685 | 653 | .irqs = rk816_battery_irqs, |
---|
686 | 654 | .num_irqs = ARRAY_SIZE(rk816_battery_irqs), |
---|
.. | .. |
---|
691 | 659 | .init_ack_masked = true, |
---|
692 | 660 | }; |
---|
693 | 661 | |
---|
694 | | -static struct regmap_irq_chip rk817_irq_chip = { |
---|
| 662 | +static const struct regmap_irq_chip rk817_irq_chip = { |
---|
695 | 663 | .name = "rk817", |
---|
696 | 664 | .irqs = rk817_irqs, |
---|
697 | 665 | .num_irqs = ARRAY_SIZE(rk817_irqs), |
---|
.. | .. |
---|
719 | 687 | static struct rk808_reg_data *suspend_reg, *resume_reg; |
---|
720 | 688 | static int suspend_reg_num, resume_reg_num; |
---|
721 | 689 | |
---|
722 | | -static void rk805_device_shutdown(void) |
---|
723 | | -{ |
---|
724 | | - int ret; |
---|
725 | | - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); |
---|
726 | | - |
---|
727 | | - if (!rk808) |
---|
728 | | - return; |
---|
729 | | - |
---|
730 | | - ret = regmap_update_bits(rk808->regmap, |
---|
731 | | - RK805_DEV_CTRL_REG, |
---|
732 | | - DEV_OFF, DEV_OFF); |
---|
733 | | - if (ret) |
---|
734 | | - dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
---|
735 | | -} |
---|
736 | | - |
---|
737 | 690 | static void rk805_device_shutdown_prepare(void) |
---|
738 | 691 | { |
---|
739 | 692 | int ret; |
---|
.. | .. |
---|
749 | 702 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
---|
750 | 703 | } |
---|
751 | 704 | |
---|
752 | | -static void rk808_device_shutdown(void) |
---|
753 | | -{ |
---|
754 | | - int ret; |
---|
755 | | - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); |
---|
756 | | - |
---|
757 | | - if (!rk808) |
---|
758 | | - return; |
---|
759 | | - |
---|
760 | | - ret = regmap_update_bits(rk808->regmap, |
---|
761 | | - RK808_DEVCTRL_REG, |
---|
762 | | - DEV_OFF_RST, DEV_OFF_RST); |
---|
763 | | - if (ret) |
---|
764 | | - dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
---|
765 | | -} |
---|
766 | | - |
---|
767 | | -static void rk816_device_shutdown(void) |
---|
768 | | -{ |
---|
769 | | - int ret; |
---|
770 | | - struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); |
---|
771 | | - |
---|
772 | | - if (!rk808) |
---|
773 | | - return; |
---|
774 | | - |
---|
775 | | - ret = regmap_update_bits(rk808->regmap, |
---|
776 | | - RK816_DEV_CTRL_REG, |
---|
777 | | - DEV_OFF, DEV_OFF); |
---|
778 | | - if (ret) |
---|
779 | | - dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
---|
780 | | -} |
---|
781 | | - |
---|
782 | 705 | static void rk817_shutdown_prepare(void) |
---|
783 | 706 | { |
---|
784 | 707 | int ret; |
---|
785 | 708 | struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); |
---|
786 | 709 | |
---|
787 | | - /* close int when power off */ |
---|
| 710 | + /* close rtc int when power off */ |
---|
788 | 711 | regmap_update_bits(rk808->regmap, |
---|
789 | 712 | RK817_INT_STS_MSK_REG0, |
---|
790 | | - 0xff, 0xff); |
---|
791 | | - regmap_update_bits(rk808->regmap, |
---|
792 | | - RK817_INT_STS_MSK_REG1, |
---|
793 | | - 0xff, 0xff); |
---|
794 | | - regmap_update_bits(rk808->regmap, |
---|
795 | | - RK817_INT_STS_MSK_REG2, |
---|
796 | | - 0xff, 0xff); |
---|
| 713 | + (0x3 << 5), (0x3 << 5)); |
---|
797 | 714 | regmap_update_bits(rk808->regmap, |
---|
798 | 715 | RK817_RTC_INT_REG, |
---|
799 | 716 | (0x3 << 2), (0x0 << 2)); |
---|
800 | | - |
---|
801 | | - dev_info(&rk808_i2c_client->dev, "disabled int when device shutdown!\n"); |
---|
802 | 717 | |
---|
803 | 718 | if (rk808->pins && rk808->pins->p && rk808->pins->power_off) { |
---|
804 | 719 | ret = regmap_update_bits(rk808->regmap, |
---|
.. | .. |
---|
832 | 747 | mdelay(2); |
---|
833 | 748 | } |
---|
834 | 749 | |
---|
835 | | -static void rk818_device_shutdown(void) |
---|
| 750 | +static void rk8xx_device_shutdown(void) |
---|
836 | 751 | { |
---|
837 | 752 | int ret; |
---|
| 753 | + unsigned int reg, bit; |
---|
838 | 754 | struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); |
---|
839 | 755 | |
---|
840 | | - if (!rk808) |
---|
| 756 | + switch (rk808->variant) { |
---|
| 757 | + case RK805_ID: |
---|
| 758 | + reg = RK805_DEV_CTRL_REG; |
---|
| 759 | + bit = DEV_OFF; |
---|
| 760 | + break; |
---|
| 761 | + case RK808_ID: |
---|
| 762 | + reg = RK808_DEVCTRL_REG, |
---|
| 763 | + bit = DEV_OFF_RST; |
---|
| 764 | + break; |
---|
| 765 | + case RK816_ID: |
---|
| 766 | + reg = RK816_DEV_CTRL_REG; |
---|
| 767 | + bit = DEV_OFF; |
---|
| 768 | + break; |
---|
| 769 | + case RK818_ID: |
---|
| 770 | + reg = RK818_DEVCTRL_REG; |
---|
| 771 | + bit = DEV_OFF; |
---|
| 772 | + break; |
---|
| 773 | + default: |
---|
841 | 774 | return; |
---|
| 775 | + } |
---|
842 | 776 | |
---|
843 | | - ret = regmap_update_bits(rk808->regmap, |
---|
844 | | - RK818_DEVCTRL_REG, |
---|
845 | | - DEV_OFF, DEV_OFF); |
---|
| 777 | + ret = regmap_update_bits(rk808->regmap, reg, bit, bit); |
---|
846 | 778 | if (ret) |
---|
847 | 779 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
---|
848 | 780 | } |
---|
.. | .. |
---|
1205 | 1137 | void (*of_property_prepare_fn)(struct rk808 *rk808, |
---|
1206 | 1138 | struct device *dev) = NULL; |
---|
1207 | 1139 | int (*pinctrl_init)(struct device *dev, struct rk808 *rk808) = NULL; |
---|
| 1140 | + void (*device_shutdown_fn)(void) = NULL; |
---|
1208 | 1141 | |
---|
1209 | 1142 | rk808 = devm_kzalloc(&client->dev, sizeof(*rk808), GFP_KERNEL); |
---|
1210 | 1143 | if (!rk808) |
---|
.. | .. |
---|
1251 | 1184 | suspend_reg_num = ARRAY_SIZE(rk805_suspend_reg); |
---|
1252 | 1185 | resume_reg = rk805_resume_reg; |
---|
1253 | 1186 | resume_reg_num = ARRAY_SIZE(rk805_resume_reg); |
---|
1254 | | - rk808->pm_pwroff_fn = rk805_device_shutdown; |
---|
| 1187 | + device_shutdown_fn = rk8xx_device_shutdown; |
---|
1255 | 1188 | rk808->pm_pwroff_prep_fn = rk805_device_shutdown_prepare; |
---|
1256 | 1189 | break; |
---|
1257 | 1190 | case RK808_ID: |
---|
.. | .. |
---|
1261 | 1194 | nr_pre_init_regs = ARRAY_SIZE(rk808_pre_init_reg); |
---|
1262 | 1195 | cells = rk808s; |
---|
1263 | 1196 | nr_cells = ARRAY_SIZE(rk808s); |
---|
1264 | | - rk808->pm_pwroff_fn = rk808_device_shutdown; |
---|
| 1197 | + device_shutdown_fn = rk8xx_device_shutdown; |
---|
1265 | 1198 | break; |
---|
1266 | 1199 | case RK816_ID: |
---|
1267 | 1200 | rk808->regmap_cfg = &rk816_regmap_config; |
---|
.. | .. |
---|
1277 | 1210 | suspend_reg_num = ARRAY_SIZE(rk816_suspend_reg); |
---|
1278 | 1211 | resume_reg = rk816_resume_reg; |
---|
1279 | 1212 | resume_reg_num = ARRAY_SIZE(rk816_resume_reg); |
---|
1280 | | - rk808->pm_pwroff_fn = rk816_device_shutdown; |
---|
| 1213 | + device_shutdown_fn = rk8xx_device_shutdown; |
---|
1281 | 1214 | break; |
---|
1282 | 1215 | case RK818_ID: |
---|
1283 | 1216 | rk808->regmap_cfg = &rk818_regmap_config; |
---|
.. | .. |
---|
1292 | 1225 | suspend_reg_num = ARRAY_SIZE(rk818_suspend_reg); |
---|
1293 | 1226 | resume_reg = rk818_resume_reg; |
---|
1294 | 1227 | resume_reg_num = ARRAY_SIZE(rk818_resume_reg); |
---|
1295 | | - rk808->pm_pwroff_fn = rk818_device_shutdown; |
---|
| 1228 | + device_shutdown_fn = rk8xx_device_shutdown; |
---|
1296 | 1229 | break; |
---|
1297 | 1230 | case RK809_ID: |
---|
1298 | 1231 | case RK817_ID: |
---|
.. | .. |
---|
1402 | 1335 | if (!pm_power_off_prepare) |
---|
1403 | 1336 | pm_power_off_prepare = rk808->pm_pwroff_prep_fn; |
---|
1404 | 1337 | |
---|
1405 | | - if (rk808->pm_pwroff_fn) { |
---|
| 1338 | + if (device_shutdown_fn) { |
---|
1406 | 1339 | register_syscore_ops(&rk808_syscore_ops); |
---|
1407 | 1340 | /* power off system in the syscore shutdown ! */ |
---|
1408 | | - pm_shutdown = rk808->pm_pwroff_fn; |
---|
| 1341 | + pm_shutdown = device_shutdown_fn; |
---|
1409 | 1342 | } |
---|
1410 | 1343 | } |
---|
1411 | 1344 | |
---|
.. | .. |
---|
1433 | 1366 | struct rk808 *rk808 = i2c_get_clientdata(client); |
---|
1434 | 1367 | |
---|
1435 | 1368 | regmap_del_irq_chip(client->irq, rk808->irq_data); |
---|
1436 | | - mfd_remove_devices(&client->dev); |
---|
1437 | 1369 | |
---|
1438 | 1370 | /** |
---|
1439 | 1371 | * pm_power_off may points to a function from another module. |
---|
.. | .. |
---|
1474 | 1406 | } |
---|
1475 | 1407 | |
---|
1476 | 1408 | switch (rk808->variant) { |
---|
| 1409 | + case RK805_ID: |
---|
| 1410 | + ret = regmap_update_bits(rk808->regmap, |
---|
| 1411 | + RK805_GPIO_IO_POL_REG, |
---|
| 1412 | + SLP_SD_MSK, |
---|
| 1413 | + SLEEP_FUN); |
---|
| 1414 | + break; |
---|
1477 | 1415 | case RK809_ID: |
---|
1478 | 1416 | case RK817_ID: |
---|
1479 | 1417 | if (rk808->pins && rk808->pins->p && rk808->pins->sleep) { |
---|