]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/blame - drivers/mfd/khadas-mcu.c
Merge tag 'for-linus-5.9-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mirror_ubuntu-hirsute-kernel.git] / drivers / mfd / khadas-mcu.c
CommitLineData
6c27219e
NA
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Driver for Khadas System control Microcontroller
4 *
5 * Copyright (C) 2020 BayLibre SAS
6 *
7 * Author(s): Neil Armstrong <narmstrong@baylibre.com>
8 */
9#include <linux/bitfield.h>
10#include <linux/i2c.h>
11#include <linux/mfd/core.h>
12#include <linux/mfd/khadas-mcu.h>
13#include <linux/module.h>
14#include <linux/regmap.h>
15
16static bool khadas_mcu_reg_volatile(struct device *dev, unsigned int reg)
17{
18 if (reg >= KHADAS_MCU_USER_DATA_0_REG &&
19 reg < KHADAS_MCU_PWR_OFF_CMD_REG)
20 return true;
21
22 switch (reg) {
23 case KHADAS_MCU_PWR_OFF_CMD_REG:
24 case KHADAS_MCU_PASSWD_START_REG:
25 case KHADAS_MCU_CHECK_VEN_PASSWD_REG:
26 case KHADAS_MCU_CHECK_USER_PASSWD_REG:
27 case KHADAS_MCU_WOL_INIT_START_REG:
28 case KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG:
29 return true;
30 default:
31 return false;
32 }
33}
34
35static bool khadas_mcu_reg_writeable(struct device *dev, unsigned int reg)
36{
37 switch (reg) {
38 case KHADAS_MCU_PASSWD_VEN_0_REG:
39 case KHADAS_MCU_PASSWD_VEN_1_REG:
40 case KHADAS_MCU_PASSWD_VEN_2_REG:
41 case KHADAS_MCU_PASSWD_VEN_3_REG:
42 case KHADAS_MCU_PASSWD_VEN_4_REG:
43 case KHADAS_MCU_PASSWD_VEN_5_REG:
44 case KHADAS_MCU_MAC_0_REG:
45 case KHADAS_MCU_MAC_1_REG:
46 case KHADAS_MCU_MAC_2_REG:
47 case KHADAS_MCU_MAC_3_REG:
48 case KHADAS_MCU_MAC_4_REG:
49 case KHADAS_MCU_MAC_5_REG:
50 case KHADAS_MCU_USID_0_REG:
51 case KHADAS_MCU_USID_1_REG:
52 case KHADAS_MCU_USID_2_REG:
53 case KHADAS_MCU_USID_3_REG:
54 case KHADAS_MCU_USID_4_REG:
55 case KHADAS_MCU_USID_5_REG:
56 case KHADAS_MCU_VERSION_0_REG:
57 case KHADAS_MCU_VERSION_1_REG:
58 case KHADAS_MCU_DEVICE_NO_0_REG:
59 case KHADAS_MCU_DEVICE_NO_1_REG:
60 case KHADAS_MCU_FACTORY_TEST_REG:
61 case KHADAS_MCU_SHUTDOWN_NORMAL_STATUS_REG:
62 return false;
63 default:
64 return true;
65 }
66}
67
68static const struct regmap_config khadas_mcu_regmap_config = {
69 .reg_bits = 8,
70 .reg_stride = 1,
71 .val_bits = 8,
72 .max_register = KHADAS_MCU_CMD_FAN_STATUS_CTRL_REG,
73 .volatile_reg = khadas_mcu_reg_volatile,
74 .writeable_reg = khadas_mcu_reg_writeable,
75 .cache_type = REGCACHE_RBTREE,
76};
77
78static struct mfd_cell khadas_mcu_fan_cells[] = {
79 /* VIM1/2 Rev13+ and VIM3 only */
80 { .name = "khadas-mcu-fan-ctrl", },
81};
82
83static struct mfd_cell khadas_mcu_cells[] = {
84 { .name = "khadas-mcu-user-mem", },
85};
86
87static int khadas_mcu_probe(struct i2c_client *client,
88 const struct i2c_device_id *id)
89{
90 struct device *dev = &client->dev;
91 struct khadas_mcu *ddata;
92 int ret;
93
94 ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
95 if (!ddata)
96 return -ENOMEM;
97
98 i2c_set_clientdata(client, ddata);
99
100 ddata->dev = dev;
101
102 ddata->regmap = devm_regmap_init_i2c(client, &khadas_mcu_regmap_config);
103 if (IS_ERR(ddata->regmap)) {
104 ret = PTR_ERR(ddata->regmap);
105 dev_err(dev, "Failed to allocate register map: %d\n", ret);
106 return ret;
107 }
108
109 ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
110 khadas_mcu_cells,
111 ARRAY_SIZE(khadas_mcu_cells),
112 NULL, 0, NULL);
113 if (ret)
114 return ret;
115
116 if (of_find_property(dev->of_node, "#cooling-cells", NULL))
117 return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
118 khadas_mcu_fan_cells,
119 ARRAY_SIZE(khadas_mcu_fan_cells),
120 NULL, 0, NULL);
121
122 return 0;
123}
124
125static const struct of_device_id khadas_mcu_of_match[] = {
126 { .compatible = "khadas,mcu", },
127 {},
128};
129MODULE_DEVICE_TABLE(of, khadas_mcu_of_match);
130
131static struct i2c_driver khadas_mcu_driver = {
132 .driver = {
133 .name = "khadas-mcu-core",
134 .of_match_table = of_match_ptr(khadas_mcu_of_match),
135 },
136 .probe = khadas_mcu_probe,
137};
138module_i2c_driver(khadas_mcu_driver);
139
140MODULE_DESCRIPTION("Khadas MCU core driver");
141MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
142MODULE_LICENSE("GPL v2");