LMS 2012
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
d_power.c
Go to the documentation of this file.
1 /*
2  * LEGO® MINDSTORMS EV3
3  *
4  * Copyright (C) 2010-2013 The LEGO Group
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  */
20 
21 
30 #ifndef PCASM
31 #include <asm/types.h>
32 #endif
33 
34 #define HW_ID_SUPPORT
35 
36 #include "../../lms2012/source/lms2012.h"
37 #include "../../lms2012/source/am1808.h"
38 
39 
40 #define MODULE_NAME "power_module"
41 #define DEVICE1_NAME POWER_DEVICE
42 
43 static int ModuleInit(void);
44 static void ModuleExit(void);
45 
46 #define __USE_POSIX
47 
48 #include <linux/kernel.h>
49 #include <linux/fs.h>
50 
51 #include <linux/sched.h>
52 
53 
54 #ifndef PCASM
55 #include <linux/hrtimer.h>
56 
57 #include <linux/mm.h>
58 #include <linux/hrtimer.h>
59 
60 #include <linux/init.h>
61 #include <linux/uaccess.h>
62 #include <linux/debugfs.h>
63 
64 #include <linux/ioport.h>
65 #include <asm/gpio.h>
66 #include <asm/io.h>
67 #include <linux/module.h>
68 #include <linux/miscdevice.h>
69 #include <asm/uaccess.h>
70 
71 MODULE_LICENSE("GPL");
72 MODULE_AUTHOR("The LEGO Group");
75 
76 module_init(ModuleInit);
77 module_exit(ModuleExit);
78 
79 #else
80 // Keep Eclipse happy
81 #endif
82 
83 
84 #ifdef DEBUG_D_POWER
85 #define DEBUG
86 #endif
87 
88 
89 int Hw = 0;
90 
92 {
98 };
99 
100 
102 
110 INPIN EP2_PowerPin[POWER_PINS] =
111 {
112  { GP6_5 , NULL, 0 }, // P_EN
113  { GP6_11 , NULL, 0 }, // 5VPENON
114  { GP8_8 , NULL, 0 }, // SW_RECHARGE
115  { GP6_2 , NULL, 0 } // ADCACK
116 };
117 
118 
119 INPIN FINALB_PowerPin[POWER_PINS] =
120 {
121  { GP6_5 , NULL, 0 }, // P_EN
122  { GP6_11 , NULL, 0 }, // 5VPENON
123  { GP8_8 , NULL, 0 }, // SW_RECHARGE
124  { GP2_7 , NULL, 0 } // TP4
125 };
126 
127 
128 INPIN FINAL_PowerPin[POWER_PINS] =
129 {
130  { GP6_5 , NULL, 0 }, // P_EN
131  { GP6_11 , NULL, 0 }, // 5VPENON
132  { GP8_8 , NULL, 0 }, // SW_RECHARGE
133  { GP2_7 , NULL, 0 } // TP4
134 };
135 
136 
137 /* \endverbatim
138  * \n
139  */
140 
141 
143 {
144  [FINAL] = FINAL_PowerPin, // FINAL platform
145  [FINALB] = FINALB_PowerPin, // FINALB platform
146  [EP2] = EP2_PowerPin, // EP2 platform
147 };
148 
149 
150 //*****************************************************************************
151 
152 static void __iomem *GpioBase;
153 
154 void SetGpio(int Pin)
155 {
156  int Tmp = 0;
157  void __iomem *Reg;
158 
159  if (Pin >= 0)
160  {
161  while ((MuxRegMap[Tmp].Pin != -1) && (MuxRegMap[Tmp].Pin != Pin))
162  {
163  Tmp++;
164  }
165  if (MuxRegMap[Tmp].Pin == Pin)
166  {
167  Reg = da8xx_syscfg0_base + 0x120 + (MuxRegMap[Tmp].MuxReg << 2);
168 
169  *(u32*)Reg &= MuxRegMap[Tmp].Mask;
170  *(u32*)Reg |= MuxRegMap[Tmp].Mode;
171 
172  #ifdef DEBUG
173  printk(" GP%d_%-2d 0x%08X and 0x%08X or 0x%08X\n",(Pin >> 4),(Pin & 0x0F),(u32)Reg, MuxRegMap[Tmp].Mask, MuxRegMap[Tmp].Mode);
174  #endif
175  }
176  else
177  {
178  printk("* GP%d_%-2d ********* ERROR not found *********\n",(Pin >> 4),(Pin & 0x0F));
179  }
180  }
181 }
182 
183 
184 void InitGpio(void)
185 {
186  int Pin;
187 
188  // unlock
189  REGUnlock;
190 
191 #ifdef DEBUG
192  printk(" Power\n");
193 #endif
194  memcpy(PowerPin,pPowerPin[Hw],sizeof(EP2_PowerPin));
195  if (memcmp((const void*)PowerPin,(const void*)pPowerPin[Hw],sizeof(EP2_PowerPin)) != 0)
196  {
197  printk("%s PowerPin tabel broken!\n",MODULE_NAME);
198  }
199 
200  for (Pin = 0;Pin < POWER_PINS;Pin++)
201  {
202  if (PowerPin[Pin].Pin >= 0)
203  {
204  PowerPin[Pin].pGpio = (struct gpio_controller *__iomem)(GpioBase + ((PowerPin[Pin].Pin >> 5) * 0x28) + 0x10);
205  PowerPin[Pin].Mask = (1 << (PowerPin[Pin].Pin & 0x1F));
206 
207  SetGpio(PowerPin[Pin].Pin);
208  }
209  }
210 
211  // lock
212  REGLock;
213 }
214 
215 
216 #define POWEROn {\
217  (*PowerPin[P_EN].pGpio).set_data = PowerPin[P_EN].Mask;\
218  (*PowerPin[P_EN].pGpio).dir &= ~PowerPin[P_EN].Mask;\
219  (*PowerPin[PENON].pGpio).set_data = PowerPin[PENON].Mask;\
220  (*PowerPin[PENON].pGpio).dir &= ~PowerPin[PENON].Mask;\
221  }
222 
223 
224 #define ACCUFloat {\
225  (*PowerPin[SW_RECHARGE].pGpio).dir |= PowerPin[SW_RECHARGE].Mask;\
226  }
227 
228 
229 #define ACCURead ((*PowerPin[SW_RECHARGE].pGpio).in_data & PowerPin[SW_RECHARGE].Mask)
230 
231 
232 #define TESTOn {\
233  (*PowerPin[TESTPIN].pGpio).set_data = PowerPin[TESTPIN].Mask;\
234  (*PowerPin[TESTPIN].pGpio).dir &= ~PowerPin[TESTPIN].Mask;\
235  }
236 
237 #define TESTOff {\
238  (*PowerPin[TESTPIN].pGpio).clr_data = PowerPin[TESTPIN].Mask;\
239  (*PowerPin[TESTPIN].pGpio).dir &= ~PowerPin[TESTPIN].Mask;\
240  }
241 
242 
243 // DEVICE1 ********************************************************************
244 
245 static int Device1Ioctl(struct inode *pNode, struct file *File, unsigned int Request, unsigned long Pointer)
246 {
247  /* ignored */
248 
249  return (0);
250 }
251 
252 
253 static ssize_t Device1Write(struct file *File,const char *Buffer,size_t Count,loff_t *Data)
254 {
255  char Buf[1];
256  int Lng = 0;
257 
258  if (Count == 1)
259  {
260  copy_from_user(Buf,Buffer,Count);
261  if (Buf[0])
262  {
263  TESTOn;
264  }
265  else
266  {
267  TESTOff;
268  }
269  }
270 
271  Lng = Count;
272 
273  return (Lng);
274 }
275 
276 
277 static ssize_t Device1Read(struct file *File,char *Buffer,size_t Count,loff_t *Offset)
278 {
279  int Lng = 0;
280  char Accu;
281 
282  if (ACCURead)
283  {
284  Accu = '0';
285  }
286  else
287  {
288  Accu = '1';
289  }
290 
291  Lng = snprintf(Buffer,Count,"%c\r",Accu);
292 
293  return (Lng);
294 }
295 
296 
297 static const struct file_operations Device1Entries =
298 {
299  .owner = THIS_MODULE,
300  .read = Device1Read,
301  .write = Device1Write,
302  .ioctl = Device1Ioctl
303 };
304 
305 
306 static struct miscdevice Device1 =
307 {
308  MISC_DYNAMIC_MINOR,
309  DEVICE1_NAME,
310  &Device1Entries
311 };
312 
313 
314 static int Device1Init(void)
315 {
316  int Result = -1;
317 
318  Result = misc_register(&Device1);
319  if (Result)
320  {
321  printk(" %s device register failed\n",DEVICE1_NAME);
322  }
323  else
324  {
325 #ifdef DEBUG
326  printk(" %s device register succes\n",DEVICE1_NAME);
327 #endif
328  }
329 
330  return (Result);
331 }
332 
333 
334 static void Device1Exit(void)
335 {
336  misc_deregister(&Device1);
337 #ifdef DEBUG
338  printk(" %s device unregistered\n",DEVICE1_NAME);
339 #endif
340 }
341 
342 
343 // MODULE *********************************************************************
344 
345 
346 #ifndef PCASM
347 module_param (HwId, charp, 0);
348 #endif
349 
350 static int ModuleInit(void)
351 {
352  Hw = HWID;
353 
354  if (Hw < PLATFORM_START)
355  {
356  Hw = PLATFORM_START;
357  }
358  if (Hw > PLATFORM_END)
359  {
360  Hw = PLATFORM_END;
361  }
362 
363 #ifdef DEBUG
364  printk("%s init started\n",MODULE_NAME);
365 #endif
366 
367  if (request_mem_region(DA8XX_GPIO_BASE,0xD8,MODULE_NAME) >= 0)
368  {
369  GpioBase = (void*)ioremap(DA8XX_GPIO_BASE,0xD8);
370  if (GpioBase != NULL)
371  {
372 #ifdef DEBUG
373  printk("%s gpio address mapped\n",MODULE_NAME);
374 #endif
375 
376  InitGpio();
377  POWEROn;
378  TESTOff;
379  ACCUFloat;
380 
381  Device1Init();
382  }
383  }
384 
385  return (0);
386 }
387 
388 
389 static void ModuleExit(void)
390 {
391 #ifdef DEBUG
392  printk("%s exit started\n",MODULE_NAME);
393 #endif
394 
395  TESTOff;
396  Device1Exit();
397  iounmap(GpioBase);
398 
399 }
#define TESTOff
Definition: d_power.c:237
#define REGLock
Definition: am1808.h:235
#define snprintf
Definition: c_input.c:141
MRM MuxRegMap[]
Definition: am1808.h:59
GPIOC pGpio
Definition: am1808.h:225
#define REGUnlock
Definition: am1808.h:230
Definition: am1808.h:222
MODULE_SUPPORTED_DEVICE(DEVICE1_NAME)
#define TESTOn
Definition: d_power.c:232
#define EP2
Schematics revision D.
Definition: lms2012.h:99
Definition: am1808.h:39
Definition: d_power.c:93
#define FINAL
Final prototype.
Definition: lms2012.h:101
MODULE_LICENSE("GPL")
#define POWEROn
Definition: d_power.c:216
u16 MuxReg
Definition: am1808.h:53
INPIN * pPowerPin[]
Definition: d_power.c:142
INPIN PowerPin[POWER_PINS]
Definition: d_power.c:101
#define ACCUFloat
Definition: d_power.c:224
Definition: d_power.c:94
int Pin
Definition: am1808.h:224
#define FINALB
Schematics revision B and C.
Definition: lms2012.h:100
int Hw
Definition: d_power.c:89
module_param(HwId, charp, 0)
Definition: am1808.h:35
PowerPins
Definition: d_power.c:91
u32 Mask
Definition: am1808.h:226
char Buffer[1024]
Definition: c_wifi.c:102
#define MODULE_NAME
Definition: d_power.c:40
module_exit(ModuleExit)
void InitGpio(void)
Definition: d_power.c:184
MODULE_AUTHOR("The LEGO Group")
#define DEVICE1_NAME
Definition: d_power.c:41
Definition: am1808.h:39
Definition: am1808.h:39
void SetGpio(int Pin)
Definition: d_power.c:154
uint32_t u32
Definition: common.h:158
#define ACCURead
Definition: d_power.c:229
MODULE_DESCRIPTION(MODULE_NAME)
#define PLATFORM_END
Newest supported hardware (newer versions will use this)
Definition: lms2012.h:105
Definition: am1808.h:41
module_init(ModuleInit)
#define PLATFORM_START
Oldest supported hardware (older versions will use this)
Definition: lms2012.h:104
#define NULL