• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
sdio_tnetw1150_dump(int count)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 
sdio_tnetw1150_read_proc(char * page,char ** start,off_t off,int count,int * eof,void * data)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;
SDIO_TNETWInit(SDIO_TNETWConfigParams * params)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 
SDIO_TNETWReset(SDIO_TNETWConfigParams * params)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 
config_partition(SDIO_Handle sdioHandle,int partition_no,Peripheral_Address start_addr,SDIO_BufferLength part_size)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 */
SDIO_TNETWConfig(SDIO_Handle sdioHandle,Peripheral_ConfigParams ** peripheral_info)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 */
SDIO_ConvertTNETWToSDIOMaster(Peripheral_Address in_tnetw_address,SDIO_BufferLength packet_size)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 
SDIO_TNETW_Set_ELP_Reg(SDIO_Handle sdioHandle,Peripheral_Address start_addr,unsigned int data)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 
SDIO_TNETW_Get_ELP_Reg(SDIO_Handle sdioHandle,Peripheral_Address start_addr,unsigned int * data)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 */
546