]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/pmic/arm/mx35_3stack/v2_0/src/mc9s08dz.c
Initial revision
[karo-tx-redboot.git] / packages / devs / pmic / arm / mx35_3stack / v2_0 / src / mc9s08dz.c
1 //==========================================================================
2 //
3 //      mc9s08dz.c
4 //
5 //      PMIC support on i.MX35 3stack platforms
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41
42 #include <redboot.h>
43 #include <stdlib.h>
44 #include <pkgconf/hal.h>
45 #include <pkgconf/devs_pmic_arm_imx35_3stack.h>
46 #include <cyg/hal/hal_arch.h>
47 #include <cyg/hal/hal_cache.h>
48 #include <cyg/hal/hal_io.h>
49 #include <cyg/hal/fsl_board.h>
50 #ifdef MXC_PMIC_I2C_ENABLED
51 #include <cyg/io/mxc_i2c.h>
52 #endif                          // MXC_PMIC_I2C_ENABLED
53 #include <cyg/io/mc9s08dz.h>
54
55 extern unsigned int system_rev;
56
57 static void mxc_pmic_init(void)
58 {
59     volatile unsigned int rev_id;
60
61 #ifdef MXC_PMIC_I2C_ENABLED
62     if (CYGHWR_DEVS_PMIC_I2C_PORT >= i2c_num)
63         return;
64 // 40kHz data rate
65     i2c_init(i2c_base_addr[CYGHWR_DEVS_PMIC_I2C_PORT], 40000);
66 #else
67 #error "Please select a valid interface"
68 #endif                          // MXC_PMIC_I2C_ENABLED
69
70     rev_id = pmic_reg(0, 0, 0);
71     diag_printf("PMIC ID: 0x%08x [Rev: ", rev_id);
72     switch (rev_id & 0x1F) {
73     case 0x10:
74         diag_printf("1.0");
75         break;
76     default:
77         diag_printf("unknown");
78         break;
79     }
80     diag_printf("]\n");
81 }
82
83 RedBoot_init(mxc_pmic_init, RedBoot_INIT_PRIO(100));
84
85 static void do_pmic(int argc, char *argv[]);
86 RedBoot_cmd("pmic",
87             "Read/Write internal PMIC register",
88             "<reg num> [value to be written]", do_pmic);
89
90 static void do_pmic(int argc, char *argv[])
91 {
92     unsigned int reg, temp, val = 0, write = 0;
93
94     if (argc == 1) {
95         diag_printf("\tRead:  pmic <reg num>\n");
96         diag_printf("\tWrite: pmic <reg num> <value to be written>\n");
97         return;
98     }
99
100     if (!parse_num(*(&argv[1]), (unsigned long *)&reg, &argv[1], ":")) {
101         diag_printf("Error: Invalid parameter\n");
102         return;
103     }
104
105     if (argc == 3) {
106         if (!parse_num(*(&argv[2]), (unsigned long *)&val, &argv[2], ":")) {
107             diag_printf("Error: Invalid parameter\n");
108             return;
109         }
110         write = 1;
111     }
112
113     temp = pmic_reg(reg, val, write);
114
115     diag_printf("\tval: 0x%08x\n\n", temp);
116 }
117
118 #ifdef MXC_PMIC_I2C_ENABLED
119 static unsigned int pmic_reg_i2c(unsigned int reg, unsigned int val,
120                                  unsigned int write)
121 {
122     struct mxc_i2c_request rq;
123     rq.dev_addr = CYGHWR_DEVS_PMIC_I2C_ADDR;
124     rq.reg_addr = reg;
125     rq.reg_addr_sz = 1;
126     rq.buffer = (unsigned char *)&val;
127     rq.buffer_sz = 1;
128     write = write ? I2C_WRITE : I2C_READ;
129     if (i2c_xfer(CYGHWR_DEVS_PMIC_I2C_PORT, &rq, write) != 0) {
130         diag_printf("Error I2C transfer\n\n");
131         return 0;
132     }
133     return val;
134 }
135 #endif                          //MXC_PMIC_I2C_ENABLED
136 /*!
137  * To read/write to a PMIC register. For write, it does another read for the
138  * actual register value.
139  *
140  * @param   reg         register number inside the PMIC
141  * @param   val         data to be written to the register; don't care for read
142  * @param   write       0 for read; 1 for write
143  *
144  * @return              the actual data in the PMIC register
145  */
146 unsigned int pmic_reg(unsigned int reg, unsigned int val, unsigned int write)
147 {
148     if (reg > MC9S08DZ_MAX_REGS) {
149         diag_printf("<reg num> = %d is invalide. Should be less then 0x28\n",
150                     reg);
151         return 0;
152     }
153 #ifdef MXC_PMIC_I2C_ENABLED
154     return pmic_reg_i2c(reg, val, write);
155 #else
156     return 0;
157 #endif                          //MXC_PMIC_I2C_ENABLED
158 }
159
160 static void mxc_pmic_detect(void)
161 {
162     struct mxc_i2c_request rq;
163     unsigned char buf[4] = { 0 };
164
165     rq.dev_addr = 0x34;
166     rq.reg_addr = 0x10;
167     rq.reg_addr_sz = 1;
168     rq.buffer = buf;
169     rq.buffer_sz = 1;
170
171     if (i2c_xfer(0, &rq, I2C_WRITE) != 0) {
172         /* v2.0 board which does not have max8660 */
173         system_rev |= 0x1 << 8;
174         /* workaround for WDOG reset pin */
175         writel(0x11, IOMUXC_BASE_ADDR + 0xC);
176         diag_printf("Board version V2.0\n");
177     } else {
178         diag_printf("Board version V1.0\n");
179     }
180
181 #ifdef CYGPKG_DEVS_ETH_FEC
182     /**
183      * if we have v2.0 board, need to enable
184      * APLite VGEN1 regulator
185      */
186     if (system_rev & 0xF00) {
187         /* set VGEN voltage to 3.3v */
188         rq.dev_addr = 0x08;
189         rq.reg_addr = 0x1E;     /* VGEN REG0 setting */
190         rq.reg_addr_sz = 1;
191         rq.buffer = buf;
192         rq.buffer_sz = 3;
193         i2c_xfer(0, &rq, I2C_READ);
194         rq.buffer_sz = 3;
195         buf[2] |= 0x3;
196         i2c_xfer(0, &rq, I2C_WRITE);
197         /* enable FEC 3v3 */
198         rq.dev_addr = 0x08;
199         rq.reg_addr = 0x20;     /* VGEN REG0 */
200         rq.reg_addr_sz = 1;
201         rq.buffer = buf;
202         rq.buffer_sz = 3;
203         i2c_xfer(0, &rq, I2C_READ);
204         rq.buffer_sz = 3;
205         buf[2] |= 0x1;
206         i2c_xfer(0, &rq, I2C_WRITE);
207     }
208 #endif
209
210 }
211
212 RedBoot_init(mxc_pmic_detect, RedBoot_INIT_PRIO(101));