bsec: update after MISC u-class update
[oweals/u-boot.git] / drivers / misc / stm32mp_fuse.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
4  */
5
6 #include <common.h>
7 #include <command.h>
8 #include <fuse.h>
9 #include <misc.h>
10 #include <errno.h>
11 #include <dm/device.h>
12 #include <dm/uclass.h>
13 #include <power/stpmic1.h>
14
15 #define STM32MP_OTP_BANK        0
16 #define STM32MP_NVM_BANK        1
17
18 /*
19  * The 'fuse' command API
20  */
21 int fuse_read(u32 bank, u32 word, u32 *val)
22 {
23         int ret;
24         struct udevice *dev;
25
26         switch (bank) {
27         case STM32MP_OTP_BANK:
28                 ret = uclass_get_device_by_driver(UCLASS_MISC,
29                                                   DM_GET_DRIVER(stm32mp_bsec),
30                                                   &dev);
31                 if (ret)
32                         return ret;
33                 ret = misc_read(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
34                                 val, 4);
35                 if (ret != 4)
36                         ret = -EINVAL;
37                 else
38                         ret = 0;
39                 break;
40
41 #ifdef CONFIG_PMIC_STPMIC1
42         case STM32MP_NVM_BANK:
43                 *val = 0;
44                 ret = stpmic1_shadow_read_byte(word, (u8 *)val);
45                 break;
46 #endif /* CONFIG_PMIC_STPMIC1 */
47
48         default:
49                 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
50                 ret = -EINVAL;
51                 break;
52         }
53
54         return ret;
55 }
56
57 int fuse_prog(u32 bank, u32 word, u32 val)
58 {
59         struct udevice *dev;
60         int ret;
61
62         switch (bank) {
63         case STM32MP_OTP_BANK:
64                 ret = uclass_get_device_by_driver(UCLASS_MISC,
65                                                   DM_GET_DRIVER(stm32mp_bsec),
66                                                   &dev);
67                 if (ret)
68                         return ret;
69                 ret = misc_write(dev, word * 4 + STM32_BSEC_OTP_OFFSET,
70                                  &val, 4);
71                 if (ret != 4)
72                         ret = -EINVAL;
73                 else
74                         ret = 0;
75                 break;
76
77 #ifdef CONFIG_PMIC_STPMIC1
78         case STM32MP_NVM_BANK:
79                 ret = stpmic1_nvm_write_byte(word, (u8 *)&val);
80                 break;
81 #endif /* CONFIG_PMIC_STPMIC1 */
82
83         default:
84                 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
85                 ret = -EINVAL;
86                 break;
87         }
88
89         return ret;
90 }
91
92 int fuse_sense(u32 bank, u32 word, u32 *val)
93 {
94         struct udevice *dev;
95         int ret;
96
97         switch (bank) {
98         case STM32MP_OTP_BANK:
99                 ret = uclass_get_device_by_driver(UCLASS_MISC,
100                                                   DM_GET_DRIVER(stm32mp_bsec),
101                                                   &dev);
102                 if (ret)
103                         return ret;
104                 ret = misc_read(dev, word * 4 + STM32_BSEC_OTP_OFFSET, val, 4);
105                 if (ret != 4)
106                         ret = -EINVAL;
107                 else
108                         ret = 0;
109                 break;
110
111 #ifdef CONFIG_PMIC_STPMIC1
112         case STM32MP_NVM_BANK:
113                 *val = 0;
114                 ret = stpmic1_nvm_read_byte(word, (u8 *)val);
115                 break;
116 #endif /* CONFIG_PMIC_STPMIC1 */
117
118         default:
119                 printf("stm32mp %s: wrong value for bank %i\n", __func__, bank);
120                 ret = -EINVAL;
121                 break;
122         }
123
124         return ret;
125 }
126
127 int fuse_override(u32 bank, u32 word, u32 val)
128 {
129         struct udevice *dev;
130         int ret;
131
132         switch (bank) {
133         case STM32MP_OTP_BANK:
134                 ret = uclass_get_device_by_driver(UCLASS_MISC,
135                                                   DM_GET_DRIVER(stm32mp_bsec),
136                                                   &dev);
137                 if (ret)
138                         return ret;
139                 ret = misc_write(dev, word * 4 + STM32_BSEC_SHADOW_OFFSET,
140                                  &val, 4);
141                 if (ret != 4)
142                         ret = -EINVAL;
143                 else
144                         ret = 0;
145                 break;
146
147 #ifdef CONFIG_PMIC_STPMIC1
148         case STM32MP_NVM_BANK:
149                 ret = stpmic1_shadow_write_byte(word, (u8 *)&val);
150                 break;
151 #endif /* CONFIG_PMIC_STPMIC1 */
152
153         default:
154                 printf("stm32mp %s: wrong value for bank %i\n",
155                        __func__, bank);
156                 ret = -EINVAL;
157                 break;
158         }
159
160         return ret;
161 }