OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / system / wlan / ti / sta_dk_4_0_4_32 / pform / linux / src / mmc_tnetw1150_api.c
1 /* mmc_tnetw1150_api.c
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License version 2 as
5  * published by the Free Software Foundation.
6  *
7  * Copyright © Texas Instruments Incorporated (Oct 2005)
8  * THIS CODE/PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDED BUT NOT LIMITED TO , THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  * This program has been modified from its original operation by Texas
12  * Instruments Incorporated. These changes are covered under version 2
13  * of the GNU General Public License, dated June 1991.
14  *
15  * Copyright © Google Inc (Feb 2008)
16  */
17 /*-------------------------------------------------------------------*/
18 #ifdef TIWLAN_MSM7000
19
20 #include <linux/module.h>
21 #include <linux/kernel.h>
22 #include <linux/version.h>
23 #include "mmc_tnetw1150_api.h"
24 #include <linux/mmc/core.h>
25
26 #include <linux/mmc/card.h>
27 #include <linux/mmc/sdio_func.h>
28
29 #define SDIO_INVALID_PERIPHERAL_ADDRESS             0x1FFFF
30
31 /* CCCR                                                 0x000000 - 0x0000ff          */
32 /* Function Basic Register (Function 1)                 0x000100 - 0x0001ff          */
33         /* 0x101          - Function 1 Extended standard I/O device type code        */
34         /* 0x102          - RFU[4-0] EnableHighPower Supports High-Power[1-0] SHP[0] */
35         /* 0x103 - 0x108  - RFU                                                      */
36         /* 0x109 - 0x10b  - Pointer to Function 1 Card Information Structure         */
37         /* 0x10c - 0x10e  - Pointer to Function 1 Code Storage Area                  */
38         /* 0x10f          - Data access window to Function 1 Code Storage Area       */
39         /* 0x110 - 0x111  - I/O block size for Function 1                            */
40         /* 0x112 - 0x1ff  - RFU                                                      */
41 /* Function Basic Register (Function 2)                 0x000200 - 0x0002ff          */
42 /* Function Basic Register (Function 3)                 0x000300 - 0x0003ff          */
43 /* Function Basic Register (Function 4)                 0x000400 - 0x0004ff          */
44 /* Function Basic Register (Function 5)                 0x000500 - 0x0005ff          */
45 /* Function Basic Register (Function 6)                 0x000600 - 0x0006ff          */
46 /* Function Basic Register (Function 7)                 0x000700 - 0x0007ff          */
47 /* RFU                                                  0x000800 - 0x000fff          */
48 /* CIS common and per-function area                     0x001000 - 0x017fff          */
49 /* RFU                                                  0x018000 - 0x01ffff          */
50 #define SDIO_FUNC1_OFFSET    0x1FFC0
51
52 typedef struct
53 {
54         Peripheral_Address mem_start_addr;
55         Peripheral_Address mem_part_size;
56         Peripheral_Address mem_end_addr;
57         Peripheral_Address reg_start_addr;
58         Peripheral_Address reg_part_size;
59         Peripheral_Address reg_end_addr;
60 } SDIO_TNETW_partitions;
61 static SDIO_TNETW_partitions TNETW_table;
62
63 static SDIO_TNETWConfigParams TNETW_params;
64
65 #ifdef CONFIG_MMC_TNET_INFO
66 typedef struct {
67         u8  scr_space[SDIO_FUNC1_OFFSET];       /* 0x000000 - 0x01ffbf;
68                                                    131072B(128kB)-64B=131008B(0x01ffc0) */
69         u32 amap_size1;                         /* 0x01ffc0 */
70         u32 amap_offset1;                       /* 0x01ffc4 */
71         u32 amap_size2;                         /* 0x01ffc8 */
72         u32 amap_offset2;                       /* 0x01ffcc */
73         u32 amap_size3;                         /* 0x01ffd0 */
74         u32 amap_offset3;                       /* 0x01ffd4 */
75         u32 amap_offset4;                       /* 0x01ffd8 */
76         u32 cis_offset;                         /* 0x01ffdc - Card Information Structure */
77         u32 csa_offset;                         /* 0x01ffe0 - Code Storage Area */
78         u8  filler[16];                         /* 0x01ffe4 - 0x01fff3 */
79         u32 wr_err_len;                         /* 0x01fff4 */
80         u32 wr_err_addr;                        /* 0x01fff8 */
81         u32 status;                             /* 0x01fffc */
82 } SDIO_FUNC1AddressMap;
83 SDIO_FUNC1AddressMap mapping;
84
85 int sdio_tnetw1150_dump(int count)
86 {
87         unsigned long from;
88         unsigned long br_offset;
89         unsigned long offset=0;
90         unsigned long p1_offset=0;
91         unsigned long p2_offset=0;
92         struct mmc_request request;
93         int lines;
94         int i=0;
95         int second_part=0;
96
97         printk("%s:\n", __FUNCTION__);
98 #define TNETW1150_OFFSET 1024
99         from=TNETW1150_OFFSET*count;
100         if((from+TNETW1150_OFFSET)>(SDIO_FUNC1_OFFSET+64))
101                 return -1;
102         br_offset=TNETW1150_OFFSET*count;
103         if(br_offset>=TNETW_params.map_reg[0].reg_size) {
104                 second_part=1;
105                 p2_offset = SDIO_DRIVER_REG_PARTITION_START;
106                 offset = TNETW_params.map_reg[1].scr_offset - TNETW_params.map_reg[0].reg_size;
107         }
108         else {
109                 p1_offset += SDIO_DOWNLOAD_PARTITION_START;
110                 offset = TNETW_params.map_reg[0].scr_offset;
111         }
112
113         request.cmd=SD_IO_RW_DIRECT;
114         request.buffer_len=1;
115         request.nob=0;
116         request.block_len=0;
117         request.buffer=&mapping.scr_space[from];
118     printk(" TNETW1150 try br_offset:0x%08lx offset:0x%08lx):\n", br_offset, offset);
119         do {
120                 request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,br_offset);
121                 if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
122                         return SDIO_FAILURE;
123                 udelay(1);
124                 *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
125                 i++;
126                 request.buffer++;
127                 br_offset++;
128         } while(i<TNETW1150_OFFSET);
129
130     printk(" TNETW1150 SCR Address Space (start:0x%08lx  end:0x%08lx part:%d offset:0x%08lx):\n", from, from+TNETW1150_OFFSET-1, second_part+1, (!second_part)?p1_offset:p2_offset);
131
132         lines=TNETW1150_OFFSET/16;
133         for(i=0; i<lines;i++, from+=16)
134         printk("SDIO:0x%04lx(SCR:0x%04lx): %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", from, (!second_part)?(from+p1_offset):(from-p2_offset+SDIO_REG_PARTITION_START), mapping.scr_space[from], mapping.scr_space[from+1], mapping.scr_space[from+2], mapping.scr_space[from+3], mapping.scr_space[from+4], mapping.scr_space[from+5], mapping.scr_space[from+6], mapping.scr_space[from+7], mapping.scr_space[from+8], mapping.scr_space[from+9], mapping.scr_space[from+10], mapping.scr_space[from+11], mapping.scr_space[from+12], mapping.scr_space[from+13], mapping.scr_space[from+14], mapping.scr_space[from+15]);
135
136     return 0;
137 }
138 EXPORT_SYMBOL(sdio_tnetw1150_dump);
139
140 int sdio_tnetw1150_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data)
141 {
142     int len=0;
143         int br_offset = SDIO_FUNC1_OFFSET;
144         struct mmc_request request;
145         u8 buf[64];
146         u8 buf3[3];
147         int bytes_to_read=64;
148         int i;
149 #define CCCR_SIZE 17
150         u8 buf_ccr[CCCR_SIZE];
151         u8 buf_ccr_offset[CCCR_SIZE] = {
152                 CCCR_SDIO_REVISION, CCCR_SD_SPECIFICATION_REVISION, CCCR_IO_ENABLE,
153                 CCCR_IO_READY, CCCR_INT_ENABLE, CCCR_INT_PENDING,
154                 CCCR_IO_ABORT, CCCR_BUS_INTERFACE_CONTOROL, CCCR_CARD_CAPABILITY,
155                 CCCR_COMMON_CIS_POINTER, CCCR_COMMON_CIS_POINTER+1, CCCR_COMMON_CIS_POINTER+2,
156                 CCCR_BUS_SUSPEND, CCCR_FUNCTION_SELECT, CCCR_EXEC_FLAGS,
157                 CCCR_READY_FLAGS, CCCR_FNO_BLOCK_SIZE,
158         };
159 #define FBR_SIZE 9
160         u8 buf_fbr[FBR_SIZE];
161         u16 buf_fbr_offset[FBR_SIZE] = {
162                 FBR_PTR_F1_CIS, FBR_PTR_F1_CIS+1, FBR_PTR_F1_CIS+2,
163                 FBR_PTR_F1_CSA, FBR_PTR_F1_CSA+1, FBR_PTR_F1_CSA+2,
164                 FBR_WIN_F1_CSA, FBR_F1_IO_BLK_SIZE, FBR_F1_IO_BLK_SIZE+1,
165         };
166
167         request.cmd=SD_IO_RW_DIRECT;
168         request.buffer_len=1;
169         request.nob=0;
170         request.block_len=0;
171         request.buffer=&buf[0];
172         for (i=0; i<bytes_to_read;i++,request.buffer++,br_offset++) {
173                 request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,br_offset);
174                 if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
175                         return SDIO_FAILURE;
176                 *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
177         }
178         memcpy(&mapping.amap_size1, &buf, 64);
179
180     count -= 80; /* some reserve */
181     len += (len<count)?sprintf(page+len, " TNETW1150 partitions:\n"):0;
182     len += (len<count)?sprintf(page+len, " Memory:      "):0;
183         len += (len<count)?sprintf(page+len, " start:0x%08lx  end:0x%08lx  size:0x%08lx bytes\n", TNETW_table.mem_start_addr, TNETW_table.mem_end_addr, TNETW_table.mem_part_size):0;
184     len += (len<count)?sprintf(page+len, " Registers:   "):0;
185         len += (len<count)?sprintf(page+len, " start:0x%08lx  end:0x%08lx  size:0x%08lx bytes\n", TNETW_table.reg_start_addr, TNETW_table.reg_end_addr, TNETW_table.reg_part_size):0;
186
187     len += (len<count)?sprintf(page+len, " SDIO Function 1 Address Map:\n"):0;
188         len += (len<count)?sprintf(page+len, " amap_size1:0x%08x  amap_offset1:0x%08x\n", mapping.amap_size1, mapping.amap_offset1):0;
189         len += (len<count)?sprintf(page+len, " amap_size2:0x%08x  amap_offset2:0x%08x\n", mapping.amap_size2, mapping.amap_offset2):0;
190         len += (len<count)?sprintf(page+len, " amap_size3:0x%08x  amap_offset3:0x%08x\n", mapping.amap_size3, mapping.amap_offset3):0;
191         len += (len<count)?sprintf(page+len, "                        amap_offset4:0x%08x\n", mapping.amap_offset4):0;
192         len += (len<count)?sprintf(page+len, " cis_offset:0x%08x  csa_offset  :0x%08x\n", mapping.cis_offset, mapping.csa_offset):0;
193         len += (len<count)?sprintf(page+len, " wr_err_len:0x%08x  wr_err_addr :0x%08x\n", mapping.wr_err_len, mapping.wr_err_addr):0;
194         len += (len<count)?sprintf(page+len, " status    :0x%08x\n", mapping.status):0;
195
196         request.cmd=SD_IO_RW_DIRECT;
197         request.buffer_len=1;
198         request.nob=0;
199         request.block_len=0;
200         request.buffer=&buf_ccr[0];
201         for (i=0; i<CCCR_SIZE;i++,request.buffer++) {
202                 request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_0,0,buf_ccr_offset[i]);
203                 if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
204                         return SDIO_FAILURE;
205                 *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
206         }
207
208     len += (len<count)?sprintf(page+len, "\n Card Common Control Registers:\n"):0;
209         len += (len<count)?sprintf(page+len, " \
210  REVISION             :0x%02x  SD_SPEC_REVISION       :0x%02x   IO_ENABLE            :0x%02x\n \
211  IO_READY             :0x%02x  INT_ENABLE             :0x%02x   INT_PENDING          :0x%02x\n \
212  IO_ABORT             :0x%02x  BUS_INTERFACE_CONTOROL :0x%02x   CARD_CAPABILITY      :0x%02x\n \
213  COMMON_CIS_POINTER[2]:0x%02x  COMMON_CIS_POINTER[1]  :0x%02x   COMMON_CIS_POINTER[0]:0x%02x\n \
214  BUS_SUSPEND          :0x%02x  FUNCTION_SELECT        :0x%02x   EXEC_FLAGS           :0x%02x\n \
215  READY_FLAGS          :0x%02x  FNO_BLOCK_SIZE         :0x%02x\n" , buf_ccr[0], buf_ccr[1], buf_ccr[2], buf_ccr[3], buf_ccr[4], buf_ccr[5], buf_ccr[6], buf_ccr[7], buf_ccr[8], buf_ccr[11], buf_ccr[10], buf_ccr[9], buf_ccr[12], buf_ccr[13], buf_ccr[14], buf_ccr[15], buf_ccr[16]):0;
216
217         request.cmd=SD_IO_RW_DIRECT;
218         request.buffer_len=1;
219         request.nob=0;
220         request.block_len=0;
221
222         request.buffer=&buf3[0];
223         for (i=0; i<3;i++,request.buffer++) {
224                 request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,FBR_PTR_F1_IO_DEV);
225                 if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
226                         return SDIO_FAILURE;
227                 *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
228         }
229
230         request.buffer=&buf_fbr[0];
231         for (i=0; i<FBR_SIZE;i++,request.buffer++) {
232                 request.arg = SDIO_CMD52_READ(0,FUNCTION_SELECT_1,0,buf_fbr_offset[i]);
233                 if(__submit_control_request(omap_mmc_dev_get_handle(), &request)!=SDIO_SUCCESS)
234                         return SDIO_FAILURE;
235                 *request.buffer = (char)omap_readw(OMAP_MMC_RSP6);
236         }
237
238     len += (len<count)?sprintf(page+len, "\n Function Basic Registers(Func 1):\n"):0;
239         len += (len<count)?sprintf(page+len, " \
240  Func 1 CSA enable and CSA support              :     0x%02x 0x%02x\n \
241  Func 1 Ext stand. I/O device i/f and type code :     0x%02x 0x%02x\n \
242  EHP|SHP[1]|SHP[0]                              :          0x%02x\n \
243  Pointer to Func 1 Card Information Structure   :0x%02x 0x%02x 0x%02x\n \
244  Pointer to Func 1 Code Storage Area            :0x%02x 0x%02x 0x%02x\n \
245  Data access window to Func 1 Code Storage Area :          0x%02x\n \
246  I/O block size for Func 1                      :     0x%02x 0x%02x\n", ((buf3[0]&0x80)>>7), ((buf3[0]&0x40)>>6), (buf3[1]&0x0f), buf3[1], (buf3[2]&0x07), buf_fbr[2], buf_fbr[1], buf_fbr[0], buf_fbr[5], buf_fbr[4], buf_fbr[3], buf_fbr[6], buf_fbr[8], buf_fbr[7]):0;
247
248     *eof = 1;
249     return len;
250 }
251 #endif /*CONFIG_MMC_TNET_STATISTICS*/
252
253
254 /*
255   Initialization of TNETW memory configuration.
256 */
257 extern int debug_level;
258 SDIO_Status SDIO_TNETWInit(SDIO_TNETWConfigParams *params)
259 {
260     /*  debug_level=3;    */   
261         /* printk("%s\n", __FUNCTION__); */
262
263         memset(&TNETW_params, 0, sizeof(SDIO_TNETWConfigParams));
264
265     if(!params) {
266                 /* printk("%s set to default\n", __FUNCTION__); */
267                 /* set to default value in case params is not presented */
268                 TNETW_params.num_of_parts = 2;
269                 /* First time initialization */
270                 TNETW_params.map_reg[0].reg_size = SDIO_DOWNLOAD_PARTITION_SIZE;
271                 TNETW_params.map_reg[0].scr_offset = SDIO_DOWNLOAD_PARTITION_START;
272                 /* After firmware has been downloaded, data memory region
273                    has to be re-initialized as following:
274                 TNETW_params.map_reg[0].reg_size = SDIO_MEM_PARTITION_START;
275                 TNETW_params.map_reg[0].scr_offset = SDIO_MEM_PARTITION_SIZE;
276                 */
277                 TNETW_params.map_reg[1].reg_size = SDIO_REG_PARTITION_SIZE;
278                 TNETW_params.map_reg[1].scr_offset = SDIO_REG_PARTITION_START;
279         }
280         else {
281                 /* printk("%s: params->num_of_parts=%d\n", __FUNCTION__, params->num_of_parts); */
282                 /* validate input parameters */
283                 switch(params->num_of_parts) {
284                 case 1:
285                         if(params->map_reg[0].reg_size > AMAP_ONE_REGION)
286                                 return SDIO_FAILURE;
287                         break;
288                 case 2:
289                         if((params->map_reg[0].reg_size + params->map_reg[1].reg_size) > AMAP_ONE_REGION)
290                                 return SDIO_FAILURE;
291                         break;
292                 case 3:
293                         if((params->map_reg[0].reg_size + params->map_reg[1].reg_size + params->map_reg[2].reg_size) > AMAP_ONE_REGION)
294                                 return SDIO_FAILURE;
295                         break;
296                 case 4:
297                         if((params->map_reg[0].reg_size + params->map_reg[1].reg_size + params->map_reg[2].reg_size + params->map_reg[3].reg_size) > AMAP_ONE_REGION)
298                                 return SDIO_FAILURE;
299                         break;
300                 default:
301                         return SDIO_FAILURE;
302                 }
303                 memcpy(&TNETW_params, params, sizeof(SDIO_TNETWConfigParams));
304         }
305
306 #ifdef CONFIG_PROC_FS
307 #ifdef CONFIG_MMC_TNET_INFO
308         create_proc_read_entry("sdio_tnetw1150", 0, NULL, sdio_tnetw1150_read_proc, NULL);
309 #endif
310 #endif
311
312         /* printk("%s completed\n", __FUNCTION__); */
313
314         return SDIO_SUCCESS;
315 }
316
317 SDIO_Status SDIO_TNETWReset(SDIO_TNETWConfigParams *params)
318 {
319         /* printk("%s\n", __FUNCTION__); */
320
321         memset(&TNETW_params, 0, sizeof(SDIO_TNETWConfigParams));
322
323         if(!params) {
324                 /* printk("%s set to default\n", __FUNCTION__); */
325                 /* set to default value in case params is not presented */
326                 TNETW_params.num_of_parts = 2;
327
328                 /* After firmware has been downloaded, data memory region
329                    has to be re-initialized as following */
330                 TNETW_params.map_reg[0].reg_size = SDIO_MEM_PARTITION_START;
331                 TNETW_params.map_reg[0].scr_offset = SDIO_MEM_PARTITION_SIZE;
332                 TNETW_params.map_reg[1].reg_size = SDIO_REG_PARTITION_SIZE;
333                 TNETW_params.map_reg[1].scr_offset = SDIO_REG_PARTITION_START;
334         }
335         else {
336                 /* printk("%s: params->num_of_parts=%d\n", __FUNCTION__, params->num_of_parts); */
337                 /* validate input parameters */
338                 switch(params->num_of_parts) {
339                 case 1:
340                         if(params->map_reg[0].reg_size > AMAP_ONE_REGION)
341                                 return SDIO_FAILURE;
342                         break;
343                 case 2:
344                         if((params->map_reg[0].reg_size + params->map_reg[1].reg_size) > AMAP_ONE_REGION)
345                                 return SDIO_FAILURE;
346                         break;
347                 case 3:
348                         if((params->map_reg[0].reg_size + params->map_reg[1].reg_size + params->map_reg[2].reg_size) > AMAP_ONE_REGION)
349                                 return SDIO_FAILURE;
350                         break;
351                 case 4:
352                         if((params->map_reg[0].reg_size + params->map_reg[1].reg_size + params->map_reg[2].reg_size + params->map_reg[3].reg_size) > AMAP_ONE_REGION)
353                                 return SDIO_FAILURE;
354                         break;
355                 default:
356                         return SDIO_FAILURE;
357                 }
358                 memcpy(&TNETW_params, params, sizeof(SDIO_TNETWConfigParams));
359         }
360
361         /* printk("%s completed\n", __FUNCTION__); */
362
363         return SDIO_SUCCESS;
364 }
365
366
367 static SDIO_Status config_partition(SDIO_Handle sdioHandle, int partition_no, Peripheral_Address start_addr, SDIO_BufferLength part_size)
368 {
369         struct sdio_func *func = (struct sdio_func *) sdioHandle;
370         u8 data;
371         int br_offset = SDIO_FUNC1_OFFSET + (partition_no-1)*8;
372         int i, rc;
373
374         /* printk("%s: partition_no=%d\n", __FUNCTION__, partition_no); */
375
376         /* Set size - write out 4 bytes by 4 requests */
377         if (partition_no < AMAP_MAX_REGIONS)
378         {
379                 for(i=0;i<4;i++,br_offset++) {
380                         data = (part_size>>(8*i))&0xFF;
381
382                         /* put R/W Flag (1 for write); Function Number(1), RAW Flag(0),
383                            Register Address - the address of the byte of data inside
384                            of the selected function that will be written
385                            (br_offset for func1),
386                            Write Data - for a direct write command, this is the byte=data,
387                            that will be written to the selected address=br_offset).
388                         */
389                         sdio_writeb(func, data, br_offset, &rc);
390                         if (rc < 0) {
391                                 printk(KERN_ERR "%s: Error writing size\n", __FUNCTION__);
392                                 return SDIO_FAILURE;
393                         }
394             /* printk("%s: offset byte=%d data=0x%08x at=0x%08x\n", __FUNCTION__, i, data, br_offset); */
395                 }
396
397         /* Set offset - write out 4 bytes by 4 requests */
398         for(i=0;i<4;i++,br_offset++) {
399             data = (start_addr>>(8*i))&0xFF;
400             sdio_writeb(func, data, br_offset, &rc);
401             if (rc < 0) {
402                 printk(KERN_ERR "%s: Error writing offset\n", __FUNCTION__);
403                 return SDIO_FAILURE;
404             }
405             /* printk("%s: offset byte=%d data=0x%08x at=0x%08x\n", __FUNCTION__, i, data, br_offset); */
406         }
407     }
408 #if 0
409     if( partition_no == 2 ) {
410         unsigned long id1;
411         for(i=0,br_offset=0x1ce34;i<4;i++,br_offset++) {
412             data = sdio_readb(func, br_offset, &rc);
413             if (rc < 0) {
414                 printk(KERN_ERR "%s: Error reading offset\n", __FUNCTION__);
415                 return SDIO_FAILURE;
416             }
417             printk("%s: offset byte=%d data=0x%08x at=0x%08x\n", __FUNCTION__, i, data, br_offset);
418         }
419         rc = sdio_memcpy_fromio(func, &id1, 0x1ce34, 4); /* Dm: Important - DO NOT REMOVE !!! */
420         if (rc < 0) {
421             printk(KERN_ERR "%s: Error reading offset\n", __FUNCTION__);
422             return SDIO_FAILURE;
423         }
424         printk("%s: data=0x%08x at=0x%08x\n", __FUNCTION__, id1, br_offset);
425     }
426 #endif
427     return SDIO_SUCCESS;
428 }
429
430 /*
431   This function configures the slave SDIO device for the required
432   operation mode.
433 */
434 SDIO_Status SDIO_TNETWConfig(SDIO_Handle sdioHandle, Peripheral_ConfigParams **peripheral_info)
435 {
436         SDIO_Status rc;
437
438         /* printk("%s\n", __FUNCTION__); */
439
440         TNETW_table.mem_start_addr = TNETW_params.map_reg[0].scr_offset;
441         TNETW_table.mem_part_size = TNETW_params.map_reg[0].reg_size;
442         TNETW_table.mem_end_addr = TNETW_table.mem_start_addr + TNETW_table.mem_part_size - 1;
443
444         TNETW_table.reg_start_addr = TNETW_params.map_reg[1].scr_offset;
445         TNETW_table.reg_part_size = TNETW_params.map_reg[1].reg_size;
446         TNETW_table.reg_end_addr = TNETW_table.reg_start_addr + TNETW_table.reg_part_size - 1;
447 #if 0
448         printk("%s: memory area: start_addr=0x%08lx end_addr=0x%08lx part_size=0x%08lx\n", __FUNCTION__, TNETW_table.mem_start_addr, TNETW_table.mem_end_addr, TNETW_table.mem_part_size);
449         printk("%s: register area: start_addr=0x%08lx end_addr=0x%08lx part_size=0x%08lx\n", __FUNCTION__, TNETW_table.reg_start_addr, TNETW_table.reg_end_addr, TNETW_table.reg_part_size);
450 #endif
451         /* Configure 17-bits address range in peripheral */
452         rc=config_partition(sdioHandle, 1, TNETW_table.mem_start_addr, TNETW_table.mem_part_size);
453         rc = (rc==SDIO_SUCCESS)?config_partition(sdioHandle, 2, TNETW_table.reg_start_addr, TNETW_table.reg_part_size):rc;
454
455         if(*peripheral_info)
456                 *peripheral_info = (void *)&TNETW_table;
457
458     /* printk("%s: TNETW1150 partitions:\n", __FUNCTION__);
459         printk("Memory   : start:0x%08lx  end:0x%08lx  size:0x%08lx bytes\n", TNETW_table.mem_start_addr, TNETW_table.mem_end_addr, TNETW_table.mem_part_size);
460         printk("Registers: start:0x%08lx  end:0x%08lx  size:0x%08lx bytes\n", TNETW_table.reg_start_addr, TNETW_table.reg_end_addr, TNETW_table.reg_part_size);
461     */
462
463         return rc;
464 }
465
466 /*
467   This function performs convertion of peripheral adddress into 17 bits
468   SDIO address. If found that the memory partition configuration must be
469   changed, the memory is re-mapped in accordance to requested address.
470 */
471 SDIO_Address SDIO_ConvertTNETWToSDIOMaster(Peripheral_Address in_tnetw_address, SDIO_BufferLength packet_size)
472 {
473         SDIO_Address out_sdio_address;
474
475 #ifdef CONFIG_SDIO_ADDRESS_MAPPING_BY_APPLICATION
476         out_sdio_address = in_tnetw_address;
477 #else
478         Peripheral_Address tnetw_last_address = in_tnetw_address + packet_size - 1;
479
480         /* printk("%s:\n", __FUNCTION__); */
481
482         if ((in_tnetw_address >= TNETW_table.mem_start_addr) && (tnetw_last_address <= TNETW_table.mem_end_addr)) {
483                 /* printk("%s part1 from=0x%08lx to 0x%08lx\n", __FUNCTION__, in_tnetw_address, tnetw_last_address); */
484                 /* address in the 1-st partition range (data memory space) */
485                 out_sdio_address = in_tnetw_address - TNETW_table.mem_start_addr;
486         }
487         else if ((in_tnetw_address >= TNETW_table.reg_start_addr) && (tnetw_last_address <= TNETW_table.reg_end_addr)) {
488                 /* printk("%s part2 from=0x%08lx to 0x%08lx\n", __FUNCTION__, in_tnetw_address, tnetw_last_address); */
489                 /* address in the 2-nd partition range (register memory space) */
490                 out_sdio_address = in_tnetw_address - TNETW_table.reg_start_addr + TNETW_table.mem_part_size;
491         }
492         else {
493                 /* printk("%s peripheral addresses from=0x%08lx to 0x%08lx is out of range\n", __FUNCTION__, in_tnetw_address, tnetw_last_address); */
494                 /* invalid address */
495                 return SDIO_INVALID_PERIPHERAL_ADDRESS;
496         }
497         /* printk("%s: in_tnetw_addr=0x%08lx out_sdio_addr=0x%08lx\n", __FUNCTION__, in_tnetw_address, out_sdio_address); */
498
499 #endif /* CONFIG_SDIO_ADDRESS_MAPPING_BY_APPLICATION */
500
501         return out_sdio_address;
502 }
503
504 SDIO_Status SDIO_TNETW_Set_ELP_Reg(SDIO_Handle sdioHandle, Peripheral_Address start_addr, unsigned int data)
505 {
506         struct sdio_func *func = (struct sdio_func *) sdioHandle;
507         u8 data1 = 0;
508         int br_offset = start_addr;
509         int i, rc;
510
511         /* Set size - write out 4 bytes by 4 requests */
512         for(i=0;i<1;i++,br_offset++) {
513                 data1 = (data>>(8*i))&0xFF;
514
515                 /* put R/W Flag (1 for write); Function Number(1), RAW Flag(0),
516                            Register Address - the address of the byte of data inside
517                            of the selected function that will be written
518                            (br_offset for func1),
519                            Write Data - for a direct write command, this is the byte=data,
520                            that will be written to the selected address=br_offset).
521                 */
522                 sdio_writeb(func, data1, br_offset, &rc);
523                 if (rc < 0) {
524                         printk(KERN_ERR "%s: Error writing size\n", __FUNCTION__);
525                         return SDIO_FAILURE;
526                 }
527         }
528         return SDIO_SUCCESS;
529 }
530
531 SDIO_Status SDIO_TNETW_Get_ELP_Reg(SDIO_Handle sdioHandle, Peripheral_Address start_addr, unsigned int *data)
532 {
533         struct sdio_func *func = (struct sdio_func *) sdioHandle;
534         int br_offset = start_addr;
535         int rc;
536
537         *(u8*)data = sdio_readb_ext(func, br_offset, &rc, 0x01);
538         if (rc) {
539                 printk(KERN_ERR "%s: Error reading sdio register (%d)\n", __FUNCTION__, rc);
540                 return SDIO_FAILURE;
541         }
542         return SDIO_SUCCESS;
543 }
544
545 #endif /* TIWLAN_MSM7000 */