1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel MAX 10 Board Management Controller chip - common code
4  *
5  * Copyright (C) 2018-2020 Intel Corporation. All rights reserved.
6  */
7 
8 #include <linux/bitfield.h>
9 #include <linux/device.h>
10 #include <linux/dev_printk.h>
11 #include <linux/mfd/core.h>
12 #include <linux/mfd/intel-m10-bmc.h>
13 #include <linux/module.h>
14 
15 static ssize_t bmc_version_show(struct device *dev,
16 				struct device_attribute *attr, char *buf)
17 {
18 	struct intel_m10bmc *ddata = dev_get_drvdata(dev);
19 	unsigned int val;
20 	int ret;
21 
22 	ret = m10bmc_sys_read(ddata, ddata->info->csr_map->build_version, &val);
23 	if (ret)
24 		return ret;
25 
26 	return sprintf(buf, "0x%x\n", val);
27 }
28 static DEVICE_ATTR_RO(bmc_version);
29 
30 static ssize_t bmcfw_version_show(struct device *dev,
31 				  struct device_attribute *attr, char *buf)
32 {
33 	struct intel_m10bmc *ddata = dev_get_drvdata(dev);
34 	unsigned int val;
35 	int ret;
36 
37 	ret = m10bmc_sys_read(ddata, ddata->info->csr_map->fw_version, &val);
38 	if (ret)
39 		return ret;
40 
41 	return sprintf(buf, "0x%x\n", val);
42 }
43 static DEVICE_ATTR_RO(bmcfw_version);
44 
45 static ssize_t mac_address_show(struct device *dev,
46 				struct device_attribute *attr, char *buf)
47 {
48 	struct intel_m10bmc *ddata = dev_get_drvdata(dev);
49 	unsigned int macaddr_low, macaddr_high;
50 	int ret;
51 
52 	ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_low, &macaddr_low);
53 	if (ret)
54 		return ret;
55 
56 	ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_high, &macaddr_high);
57 	if (ret)
58 		return ret;
59 
60 	return sysfs_emit(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
61 			  (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE1, macaddr_low),
62 			  (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE2, macaddr_low),
63 			  (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE3, macaddr_low),
64 			  (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE4, macaddr_low),
65 			  (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE5, macaddr_high),
66 			  (u8)FIELD_GET(M10BMC_N3000_MAC_BYTE6, macaddr_high));
67 }
68 static DEVICE_ATTR_RO(mac_address);
69 
70 static ssize_t mac_count_show(struct device *dev,
71 			      struct device_attribute *attr, char *buf)
72 {
73 	struct intel_m10bmc *ddata = dev_get_drvdata(dev);
74 	unsigned int macaddr_high;
75 	int ret;
76 
77 	ret = m10bmc_sys_read(ddata, ddata->info->csr_map->mac_high, &macaddr_high);
78 	if (ret)
79 		return ret;
80 
81 	return sysfs_emit(buf, "%u\n", (u8)FIELD_GET(M10BMC_N3000_MAC_COUNT, macaddr_high));
82 }
83 static DEVICE_ATTR_RO(mac_count);
84 
85 static struct attribute *m10bmc_attrs[] = {
86 	&dev_attr_bmc_version.attr,
87 	&dev_attr_bmcfw_version.attr,
88 	&dev_attr_mac_address.attr,
89 	&dev_attr_mac_count.attr,
90 	NULL,
91 };
92 
93 static const struct attribute_group m10bmc_group = {
94 	.attrs = m10bmc_attrs,
95 };
96 
97 const struct attribute_group *m10bmc_dev_groups[] = {
98 	&m10bmc_group,
99 	NULL,
100 };
101 EXPORT_SYMBOL_GPL(m10bmc_dev_groups);
102 
103 int m10bmc_dev_init(struct intel_m10bmc *m10bmc, const struct intel_m10bmc_platform_info *info)
104 {
105 	int ret;
106 
107 	m10bmc->info = info;
108 	dev_set_drvdata(m10bmc->dev, m10bmc);
109 
110 	ret = devm_mfd_add_devices(m10bmc->dev, PLATFORM_DEVID_AUTO,
111 				   info->cells, info->n_cells,
112 				   NULL, 0, NULL);
113 	if (ret)
114 		dev_err(m10bmc->dev, "Failed to register sub-devices: %d\n", ret);
115 
116 	return ret;
117 }
118 EXPORT_SYMBOL_GPL(m10bmc_dev_init);
119 
120 MODULE_DESCRIPTION("Intel MAX 10 BMC core driver");
121 MODULE_AUTHOR("Intel Corporation");
122 MODULE_LICENSE("GPL v2");
123