1 /*
2 * ===========================================================================================
3 *
4 * Filename: hal_eise.c
5 *
6 * Description: hal impl. of eise.
7 *
8 * Version: Melis3.0
9 * Create: 2020-01-08 14:20:56
10 * Revision: none
11 * Compiler:
12 *
13 * Author: ganqiuye(ganqiuye@allwinnertech.com)
14 * Organization: SWC-MPD
15 * Last Modified: 2020-04-02 17:33:33
16 *
17 * ===========================================================================================
18 */
19
20
21 #include <interrupt.h>
22 #include <hal_queue.h>
23 #include <sunxi_hal_common.h>
24 #include "sunxi_hal_eise.h"
25 #include <init.h>
26 #include <hal_clk.h>
27 #include <interrupt.h>
28 #include <log.h>
29 #define eise_err(x, arg...) printf("[EISE_ERR] (%s, %d)"x"\n", __func__, __LINE__, ##arg)
30 #define eise_warn(x, arg...) printf("[EISE_WARN] (%s, %d)"x"\n", __func__, __LINE__, ##arg)
31 #define eise_print(x, arg...) printf("[EISE] (%s, %d)"x"\n", __func__, __LINE__, ##arg)
32 #define eise_debug(x, arg...) printf("[EISE_DEBUG] (%s, %d)"x"\n", __func__, __LINE__, ##arg)
33
34 typedef enum
35 {
36 EISE_WRITE_REGISTER = 0x100,
37 EISE_READ_REGISTER,
38 ENABLE_EISE,
39 DISABLE_EISE,
40 WAIT_EISE_FINISH,
41 SET_EISE_FREQ
42 } hal_eise_transfer_cmd_t;
43
44
45 #define EISE_CLK_HIGH_WATER (700)
46 #define EISE_CLK_LOW_WATER (300)
47 #define EISE_DEFAULT_RATE (432000000)
48 #define EISE_INTERRUPT_ID (58)
49 #define EISE_BASE_ADDR (0x02300000)
50 #define CCMU_BASE_ADDR (0x03001000)
51
52 static hal_eise_t sHalEise;
53
eise_interrupt(int irq,void * dev_id)54 static irqreturn_t eise_interrupt(int irq, void* dev_id)
55 {
56 int irq_status;
57 hal_eise_t* pHe = &sHalEise;
58 hal_writel(0x00, pHe->eise_base_addr + EISE_INTERRUPT_EN);
59
60 irq_status = hal_readl(pHe->eise_base_addr + EISE_INTERRUPT_STATUS);
61 if (0x00 != (irq_status & 0x07))
62 {
63 hal_sem_post(pHe->hal_sem);
64 }
65 /*
66 if (0x01 != (irq_status & 0x01))
67 {
68 pHe->err_cnt++;
69 }
70
71 pHe->interrupt_times++;
72 */
73 return IRQ_HANDLED;
74 }
75
eise_hal_init(int32_t dev)76 static int32_t eise_hal_init(int32_t dev)
77 {
78 hal_eise_t* pHe = &sHalEise;
79 pHe->irq_id = EISE_INTERRUPT_ID;
80 pHe->eise_base_addr = EISE_BASE_ADDR;
81 pHe->ccmu_base_addr = CCMU_BASE_ADDR;
82 pHe->pclk = HAL_CLK_PLL_PERI0;
83 pHe->mclk = HAL_CLK_PERIPH_EISE;
84 hal_clk_set_parent(pHe->mclk, pHe->pclk);
85 pHe->hal_sem = hal_sem_create(0);
86 if (pHe->hal_sem == NULL)
87 {
88 eise_err("creating hal semaphore failed\n");
89 return SUNXI_HAL_ERROR;
90 }
91 int ret = request_irq(pHe->irq_id, (irq_handler_t)eise_interrupt, 0, "sunxi_eise", NULL);
92 if (ret < 0) {
93 eise_err("Request EISE Irq error! return %d\n", ret);
94 return SUNXI_HAL_ERROR;
95 } else {
96 //eise_print("Request EISE Irq success! irq_id = %d, return %d\n", pHe->irq_id, ret);
97 }
98 enable_irq(pHe->irq_id);
99 return SUNXI_HAL_OK;
100 }
101
eise_hal_uninit(int32_t dev)102 static int32_t eise_hal_uninit(int32_t dev)
103 {
104 hal_eise_t* pHe = &sHalEise;
105 hal_clock_disable(pHe->mclk);
106 free_irq(pHe->irq_id, NULL);
107 eise_print("EISE device has been removed!\n");
108 return 0;
109 }
110
eise_hal_write(int32_t dev,const char * data,uint32_t num)111 static int32_t eise_hal_write(int32_t dev, const char *data, uint32_t num)
112 {
113 return 0;
114 }
115
eise_hal_read(int32_t dev,int * data,uint32_t size)116 static int32_t eise_hal_read(int32_t dev, int *data, uint32_t size)
117 {
118 return 0;
119 }
120
eise_hal_ctl(int32_t dev,uint32_t cmd,void * arg)121 static int32_t eise_hal_ctl(int32_t dev, uint32_t cmd, void* arg)
122 {
123 hal_eise_t* pHe = &sHalEise;
124 struct eise_register reg;
125 long ret = 0;
126 int hal_sem_ret;
127 unsigned int rData = 0x5a5a5a5a;
128 memcpy(®, arg, sizeof(struct eise_register));
129 switch (cmd) {
130 case EISE_WRITE_REGISTER:
131 hal_writel(reg.value, pHe->eise_base_addr + reg.addr);
132 return 0;
133 case EISE_READ_REGISTER:
134 rData = hal_readl(pHe->eise_base_addr + reg.addr);
135 return rData;
136 case ENABLE_EISE:
137 if (hal_clock_enable(pHe->mclk))
138 eise_err("[SYS] enable eise_moduleclk failed!\n");
139 break;
140 case DISABLE_EISE:
141 hal_clock_disable(pHe->mclk);
142 break;
143 case WAIT_EISE_FINISH:
144 hal_sem_ret = hal_sem_timedwait(pHe->hal_sem, reg.value);//1 tick = 10ms
145 if (hal_sem_ret < 0)
146 eise_print("[SYS] wait_event_timeout!\n");
147 break;
148 case SET_EISE_FREQ:
149 {
150 unsigned int arg_rate = reg.value;
151 if (arg_rate >= EISE_CLK_LOW_WATER &&
152 arg_rate <= EISE_CLK_HIGH_WATER) {
153 if (!hal_clk_set_rate(pHe->mclk, arg_rate*1000000)) {
154 //eise_err("set clock failed!\n");
155 }
156 else
157 {
158 //eise_print("set clock success!");
159 }
160 }
161 //ret = hal_clk_get_rate(pHe->mclk);
162 //eise_print("eise real_fre=%ld\n", ret);
163 break;
164 }
165 default:
166 {
167 eise_warn("[SYS] do not supprot this ioctrl now!\n");
168 break;
169 }
170 }
171
172 return 0;
173 }
174
175 const sunxi_hal_driver_eise_t sunxi_hal_eise_driver =
176 {
177 .initialize = eise_hal_init,
178 .uninitialize = eise_hal_uninit,
179 .send = eise_hal_write,
180 .receive = eise_hal_read,
181 .control = eise_hal_ctl,
182 };
183
eise_driver_init(void)184 int eise_driver_init(void)
185 {
186 __log("eise hal driver init");
187 return 0;
188 }
189
190 //late_initcall(eise_driver_init);
191