Skip to content

Commit 7be2a4c

Browse files
committed
[bsp][spacemit/k1] first version
Signed-off-by: GuEe-GUI <2991707448@qq.com>
1 parent 991f0ff commit 7be2a4c

167 files changed

Lines changed: 53780 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

bsp/spacemit/dm/Kconfig

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
SOC_DM_ADC_DIR = $(SOC_DM_DIR)/adc
2+
SOC_DM_AUDIO_DIR = $(SOC_DM_DIR)/audio
3+
SOC_DM_CLK_DIR = $(SOC_DM_DIR)/clk
4+
SOC_DM_DMA_DIR = $(SOC_DM_DIR)/dma
5+
SOC_DM_DVFS_CPUFREQ_DIR = $(SOC_DM_DIR)/dvfs/cpufreq
6+
SOC_DM_ETHERNET_DIR = $(SOC_DM_DIR)/ethernet
7+
SOC_DM_GRAPHIC_FB_DIR = $(SOC_DM_DIR)/graphic/framebuffer
8+
SOC_DM_GRAPHIC_LOGO_DIR = $(SOC_DM_DIR)/graphic/logo
9+
SOC_DM_HWCRYPTO_DIR = $(SOC_DM_DIR)/hwcrypto
10+
SOC_DM_CLOCK_TIME_DIR = $(SOC_DM_DIR)/clock_time
11+
SOC_DM_I2C_DIR = $(SOC_DM_DIR)/i2c
12+
SOC_DM_INPUT_MISC_DIR = $(SOC_DM_DIR)/input/misc
13+
SOC_DM_MBOX_DIR = $(SOC_DM_DIR)/mailbox
14+
SOC_DM_MFD_DIR = $(SOC_DM_DIR)/mfd
15+
SOC_DM_NVMEM_DIR = $(SOC_DM_DIR)/nvmem
16+
SOC_DM_PCI_DIR = $(SOC_DM_DIR)/pci
17+
SOC_DM_PIC_DIR = $(RTT_DIR)/libcpu/risc-v/common/pic
18+
SOC_DM_PIN_DIR = $(SOC_DM_DIR)/pin
19+
SOC_DM_PINCTRL_DIR = $(SOC_DM_DIR)/pinctrl
20+
SOC_DM_PMDOMAIN_DIR = $(SOC_DM_DIR)/pmdomain
21+
SOC_DM_POWER_RESET_DIR = $(SOC_DM_DIR)/power/reset
22+
SOC_DM_PWM_DIR = $(SOC_DM_DIR)/pwm
23+
SOC_DM_REGULATOR_DIR = $(SOC_DM_DIR)/regulator
24+
SOC_DM_RESET_DIR = $(SOC_DM_DIR)/reset
25+
SOC_DM_RTC_DIR = $(SOC_DM_DIR)/rtc
26+
SOC_DM_SDIO_DIR = $(SOC_DM_DIR)/sdio
27+
SOC_DM_SERIAL_DIR = $(SOC_DM_DIR)/serial
28+
SOC_DM_SOC_DIR = $(SOC_DM_DIR)/soc
29+
SOC_DM_SPI_DIR = $(SOC_DM_DIR)/spi
30+
SOC_DM_THERMAL_DIR = $(SOC_DM_DIR)/thermal
31+
SOC_DM_WDT_DIR = $(SOC_DM_DIR)/watchdog

bsp/spacemit/dm/SConscript

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import os
2+
from building import *
3+
4+
cwd = GetCurrentDir()
5+
objs = []
6+
list = os.listdir(cwd)
7+
8+
for d in list:
9+
path = os.path.join(cwd, d)
10+
if os.path.isfile(os.path.join(path, 'SConscript')):
11+
objs = objs + SConscript(os.path.join(d, 'SConscript'))
12+
13+
Return('objs')

bsp/spacemit/dm/adc/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
config RT_ADC_SPACEMIT_PMIC
2+
bool "Spacemit PMIC ADC driver"
3+
depends on RT_USING_DM
4+
depends on RT_USING_ADC
5+
depends on RT_MFD_SPACEMIT_PMIC
6+
default n

bsp/spacemit/dm/adc/SConscript

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from building import *
2+
3+
group = []
4+
cwd = GetCurrentDir()
5+
CPPPATH = [cwd + '/../include']
6+
7+
src = []
8+
9+
if GetDepend(['RT_ADC_SPACEMIT_PMIC']):
10+
src += ['adc-spacemit-pmic.c']
11+
12+
group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
13+
14+
Return('group')
Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
/*
2+
* Copyright (c) 2006-2024, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2024-5-1 GuEe-GUI first version
9+
*/
10+
11+
#define DBG_TAG "adc.spacemit-pmic"
12+
#define DBG_LVL DBG_INFO
13+
#include <rtdbg.h>
14+
15+
#define __SPACEMIT_ADC_INTERNAL
16+
#include <mfd/spacemit-pmic.h>
17+
18+
#define SPACEMIT_PMIC_ADC_TIMEOUT_MS 1000
19+
20+
struct spacemit_pmic_adc
21+
{
22+
struct rt_adc_device parent;
23+
24+
int irq;
25+
26+
struct spacemit_pmic *pmic;
27+
const struct spacemit_pmic_adc_data *data;
28+
29+
struct rt_mutex lock;
30+
struct rt_completion completion;
31+
};
32+
33+
#define raw_to_spacemit_pmic_adc(raw) rt_container_of(raw, struct spacemit_pmic_adc, parent)
34+
35+
static rt_err_t spacemit_pmic_adc_enabled(struct rt_adc_device *device,
36+
rt_int8_t channel, rt_bool_t enabled)
37+
{
38+
struct spacemit_pmic_adc *pmic_adc = raw_to_spacemit_pmic_adc(device);
39+
40+
if (channel < 0 || channel >= pmic_adc->data->iio_desc_nr)
41+
{
42+
return -RT_EINVAL;
43+
}
44+
45+
return RT_EOK;
46+
}
47+
48+
static rt_err_t spacemit_pmic_adc_convert(struct rt_adc_device *device,
49+
rt_int8_t channel, rt_uint32_t *value)
50+
{
51+
rt_err_t err;
52+
rt_uint32_t tmp, adc_val_h, adc_val_l;
53+
struct spacemit_pmic_adc *pmic_adc = raw_to_spacemit_pmic_adc(device);
54+
struct spacemit_pmic *pmic = pmic_adc->pmic;
55+
56+
if (!value || channel < 0 || channel >= pmic_adc->data->iio_desc_nr)
57+
{
58+
return -RT_EINVAL;
59+
}
60+
61+
if ((err = rt_mutex_take(&pmic_adc->lock, RT_WAITING_FOREVER)))
62+
{
63+
return err;
64+
}
65+
66+
/* Reset the ADC auto register */
67+
if ((err = spacemit_pmic_update_bits(pmic, SPM8821_ADC_AUTO_REG,
68+
SPM8821_ADC_AUTO_BIT_MSK, 0)))
69+
{
70+
goto _out_lock;
71+
}
72+
73+
/* Enable the ADC : ADC_CTRL[0] */
74+
if ((err = spacemit_pmic_update_bits(pmic, SPM8821_ADC_CTRL_REG,
75+
SPM8821_ADC_CTRL_BIT_MSK, (1 << SPM8821_ADC_CTRL_EN_BIT_OFFSET))))
76+
{
77+
goto _out_lock;
78+
}
79+
80+
/* Choose the channel of adc : ADC_CFG[1] */
81+
if ((err = spacemit_pmic_update_bits(pmic, SPM8821_ADC_CFG1_REG,
82+
SPM8821_ADC_CFG1_ADC_CHNNL_SEL_BIT_MSK,
83+
(channel + SPM8821_ADC_EXTERNAL_CHANNEL_OFFSET) <<
84+
SPM8821_ADC_CFG1_ADC_CHNNL_SEL_BIT_OFFSET)))
85+
{
86+
goto _out_lock;
87+
}
88+
89+
rt_completion_init(&pmic_adc->completion);
90+
91+
/* ADC go */
92+
if ((err = spacemit_pmic_update_bits(pmic, SPM8821_ADC_CTRL_REG,
93+
SPM8821_ADC_CTRL_BIT_MSK,
94+
(1 << SPM8821_ADC_CTRL_GO_BIT_OFFSET) |
95+
(1 << SPM8821_ADC_CTRL_EN_BIT_OFFSET))))
96+
{
97+
goto _out_lock;
98+
}
99+
100+
err = rt_completion_wait(&pmic_adc->completion,
101+
rt_tick_from_millisecond(SPACEMIT_PMIC_ADC_TIMEOUT_MS));
102+
103+
if (err)
104+
{
105+
unsigned long auto_reg, cfg1, cfg2, ctrl;
106+
unsigned long enable, result_h, result_l, status;
107+
108+
ctrl = spacemit_pmic_read(pmic, SPM8821_ADC_CTRL_REG);
109+
cfg1 = spacemit_pmic_read(pmic, SPM8821_ADC_CFG1_REG);
110+
cfg2 = spacemit_pmic_read(pmic, SPM8821_ADC_CFG2_REG);
111+
auto_reg = spacemit_pmic_read(pmic, SPM8821_ADC_AUTO_REG);
112+
status = spacemit_pmic_read(pmic, SPM8821_E_STATUS_REG_BASE + 1);
113+
enable = spacemit_pmic_read(pmic, SPM8821_E_EN_REG_BASE + 1);
114+
result_h = spacemit_pmic_read(pmic,
115+
SPM8821_ADCIN0_RES_H_REG + channel * 2);
116+
result_l = spacemit_pmic_read(pmic,
117+
SPM8821_ADCIN0_RES_L_REG + channel * 2);
118+
119+
LOG_E("ADC channel %d conversion timed out: %s", channel, rt_strerror(err));
120+
LOG_E("ADC regs: ctrl=%02lx cfg1=%02lx cfg2=%02lx auto=%02lx "
121+
"status=%02lx enable=%02lx result=%02lx:%02lx",
122+
ctrl, cfg1, cfg2, auto_reg, status, enable, result_h, result_l);
123+
goto _out_lock;
124+
}
125+
126+
adc_val_h = spacemit_pmic_read(pmic, SPM8821_ADCIN0_RES_H_REG + channel * 2);
127+
128+
if ((rt_err_t)adc_val_h < 0)
129+
{
130+
err = (rt_err_t)adc_val_h;
131+
goto _out_lock;
132+
}
133+
134+
adc_val_l = spacemit_pmic_read(pmic, SPM8821_ADCIN0_RES_L_REG + channel * 2);
135+
136+
if ((rt_err_t)adc_val_l < 0)
137+
{
138+
err = (rt_err_t)adc_val_l;
139+
goto _out_lock;
140+
}
141+
142+
tmp = spacemit_pmic_read(pmic, SPM8821_VERSION_ID_REG);
143+
144+
if ((rt_err_t)tmp < 0)
145+
{
146+
err = (rt_err_t)tmp;
147+
goto _out_lock;
148+
}
149+
150+
*value = (adc_val_h << (__rt_ffs(SPM8821_ADCIN0_REG_L_BIT_MSK) - 1)) |
151+
((adc_val_l & SPM8821_ADCIN0_REG_L_BIT_MSK) >>
152+
(__rt_ffs(SPM8821_ADCIN0_REG_L_BIT_MSK) - 1));
153+
154+
if (tmp == 0)
155+
{
156+
/*
157+
* if the version of P1 is A, the data read from
158+
* the register is the inverse of the real data
159+
* and the conversion accuracy of P1 is 12 bits
160+
*/
161+
*value = 4095 - *value;
162+
}
163+
164+
err = RT_EOK;
165+
166+
_out_lock:
167+
rt_mutex_release(&pmic_adc->lock);
168+
169+
return err;
170+
}
171+
172+
static rt_uint8_t spacemit_pmic_adc_get_resolution(struct rt_adc_device *device)
173+
{
174+
return 12;
175+
}
176+
177+
static rt_int16_t spacemit_pmic_adc_get_vref(struct rt_adc_device *device)
178+
{
179+
return 3000;
180+
}
181+
182+
static const struct rt_adc_ops spacemit_pmic_adc_ops =
183+
{
184+
.enabled = spacemit_pmic_adc_enabled,
185+
.convert = spacemit_pmic_adc_convert,
186+
.get_resolution = spacemit_pmic_adc_get_resolution,
187+
.get_vref = spacemit_pmic_adc_get_vref,
188+
};
189+
190+
static void spacemit_pmic_adc_isr(int irq, void *param)
191+
{
192+
struct spacemit_pmic_adc *pmic_adc = param;
193+
194+
rt_completion_done(&pmic_adc->completion);
195+
}
196+
197+
static rt_err_t spacemit_pmic_adc_probe(struct rt_platform_device *pdev)
198+
{
199+
rt_err_t err;
200+
const char *dev_name;
201+
struct rt_device *dev = &pdev->parent;
202+
struct spacemit_pmic *pmic = pdev->priv;
203+
struct spacemit_pmic_adc *pmic_adc = rt_calloc(1, sizeof(*pmic_adc));
204+
const struct spacemit_pmic_adc_data *data = pdev->id->data;
205+
206+
if (!pmic_adc)
207+
{
208+
return -RT_ENOMEM;
209+
}
210+
211+
pmic_adc->pmic = pmic;
212+
pmic_adc->data = data;
213+
214+
if ((pmic_adc->irq = rt_dm_dev_get_irq(dev, 0)) < 0)
215+
{
216+
err = pmic_adc->irq;
217+
goto _fail;
218+
}
219+
220+
/* Enable chop */
221+
if ((err = spacemit_pmic_update_bits(pmic,
222+
SPM8821_ADC_CFG1_REG,
223+
SPM8821_ADC_CFG1_ADC_CHOP_EN_BIT_MSK,
224+
1 << SPM8821_ADC_CFG1_ADC_CHOP_EN_BIT_OFFSET)))
225+
{
226+
goto _fail;
227+
}
228+
229+
/* Set the vref: 3v3 */
230+
if ((err = spacemit_pmic_update_bits(pmic,
231+
SPM8821_ADC_CFG2_REG,
232+
SPM8821_ADC_CFG2_REF_SEL_BIT_MSK,
233+
SPM8821_ADC_CFG2_3V3_REF << SPM8821_ADC_CFG2_REF_SEL_BIT_OFFSET)))
234+
{
235+
goto _fail;
236+
}
237+
238+
/* Set adc deb num: 7 */
239+
if ((err = spacemit_pmic_update_bits(pmic,
240+
SPM8821_ADC_CFG2_REG,
241+
SPM8821_ADC_CFG2_DEB_NUM_BIT_MSK,
242+
SPM8821_ADC_CFG2_7_DEB_NUM << SPM8821_ADC_CFG2_DEB_NUM_BIT_OFFSET)))
243+
{
244+
goto _fail;
245+
}
246+
247+
dev->user_data = pmic_adc;
248+
249+
rt_dm_dev_set_name_auto(&pmic_adc->parent.parent, "adc");
250+
dev_name = rt_dm_dev_get_name(&pmic_adc->parent.parent);
251+
252+
if ((err = rt_mutex_init(&pmic_adc->lock, dev_name, RT_IPC_FLAG_PRIO)))
253+
{
254+
goto _fail;
255+
}
256+
257+
rt_completion_init(&pmic_adc->completion);
258+
259+
if ((err = rt_hw_adc_register(&pmic_adc->parent, dev_name,
260+
&spacemit_pmic_adc_ops, pmic_adc)))
261+
{
262+
rt_mutex_detach(&pmic_adc->lock);
263+
goto _fail;
264+
}
265+
266+
rt_hw_interrupt_install(pmic_adc->irq, spacemit_pmic_adc_isr, pmic_adc, "adc-spacemit-pmic");
267+
rt_hw_interrupt_umask(pmic_adc->irq);
268+
269+
rt_dm_dev_bind_fwdata(dev, RT_NULL, pmic_adc);
270+
271+
return RT_EOK;
272+
273+
_fail:
274+
rt_free(pmic_adc);
275+
276+
return err;
277+
}
278+
279+
static rt_err_t spacemit_pmic_adc_remove(struct rt_platform_device *pdev)
280+
{
281+
struct spacemit_pmic_adc *pmic_adc = pdev->parent.user_data;
282+
283+
rt_hw_interrupt_mask(pmic_adc->irq);
284+
rt_pic_detach_irq(pmic_adc->irq, pmic_adc);
285+
286+
rt_device_unregister(&pmic_adc->parent.parent);
287+
rt_mutex_detach(&pmic_adc->lock);
288+
289+
rt_free(pmic_adc);
290+
291+
return RT_EOK;
292+
}
293+
294+
static const struct rt_ofw_node_id spacemit_pmic_adc_ofw_ids[] =
295+
{
296+
{ .compatible = "pmic,adc,spm8821", .data = &spm8821_adc_data },
297+
{ /* sentinel */ }
298+
};
299+
300+
static struct rt_platform_driver spacemit_pmic_adc_driver =
301+
{
302+
.name = "spacemit-pmic-adc",
303+
.ids = spacemit_pmic_adc_ofw_ids,
304+
305+
.probe = spacemit_pmic_adc_probe,
306+
.remove = spacemit_pmic_adc_remove,
307+
};
308+
RT_PLATFORM_DRIVER_EXPORT(spacemit_pmic_adc_driver);

0 commit comments

Comments
 (0)