1 /* 2 * host_platform.c 3 * 4 * Copyright(c) 1998 - 2009 Texas Instruments. All rights reserved. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name Texas Instruments nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 #include "tidef.h" 34 #include <linux/kernel.h> 35 #include <asm/io.h> 36 #include <linux/delay.h> 37 #include <linux/platform_device.h> 38 #include <linux/wifi_tiwlan.h> 39 40 #include "host_platform.h" 41 #include "ioctl_init.h" 42 #include "WlanDrvIf.h" 43 #include "Device1273.h" 44 45 #define OS_API_MEM_ADDR 0x0000000 46 #define OS_API_REG_ADDR 0x0300000 47 #define SDIO_ATTEMPT_LONGER_DELAY_LINUX 150 48 49 static struct wifi_platform_data *wifi_control_data = NULL; 50 static struct resource *wifi_irqres = NULL; 51 52 static int wifi_probe( struct platform_device *pdev ) 53 { 54 struct wifi_platform_data *wifi_ctrl = (struct wifi_platform_data *)(pdev->dev.platform_data); 55 56 /* printk("%s\n", __FUNCTION__); */ 57 wifi_irqres = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "device_wifi_irq"); 58 #if 0 59 if (wifi_irqres) { 60 printk("wifi_irqres->start = %lu\n", (unsigned long)(wifi_irqres->start)); 61 printk("wifi_irqres->flags = %lx\n", wifi_irqres->flags); 62 } 63 #endif 64 if( wifi_ctrl ) { 65 wifi_control_data = wifi_ctrl; 66 #if 0 67 if( wifi_ctrl->set_power ) 68 wifi_ctrl->set_power(1); /* Power On */ 69 if( wifi_ctrl->set_reset ) 70 wifi_ctrl->set_reset(0); /* Reset clear */ 71 if( wifi_ctrl->set_carddetect ) 72 wifi_ctrl->set_carddetect(1); /* CardDetect (0->1) */ 73 #endif 74 } 75 return 0; 76 } 77 78 static int wifi_remove( struct platform_device *pdev ) 79 { 80 struct wifi_platform_data *wifi_ctrl = (struct wifi_platform_data *)(pdev->dev.platform_data); 81 82 /* printk("%s\n", __FUNCTION__); */ 83 if( wifi_ctrl ) { 84 if( wifi_ctrl->set_carddetect ) 85 wifi_ctrl->set_carddetect(0); /* CardDetect (1->0) */ 86 if( wifi_ctrl->set_reset ) 87 wifi_ctrl->set_reset(1); /* Reset active */ 88 if( wifi_ctrl->set_power ) 89 wifi_ctrl->set_power(0); /* Power Off */ 90 } 91 return 0; 92 } 93 94 static struct platform_driver wifi_device = { 95 .probe = wifi_probe, 96 .remove = wifi_remove, 97 .suspend = NULL, 98 .resume = NULL, 99 .driver = { 100 .name = "device_wifi", 101 }, 102 }; 103 104 static int wifi_add_dev( void ) 105 { 106 /* printk("%s\n", __FUNCTION__); */ 107 return platform_driver_register( &wifi_device ); 108 } 109 110 static void wifi_del_dev( void ) 111 { 112 /* printk("%s\n", __FUNCTION__); */ 113 platform_driver_unregister( &wifi_device ); 114 } 115 116 int wifi_set_carddetect( int on ) 117 { 118 /* printk("%s = %d\n", __FUNCTION__, on); */ 119 if( wifi_control_data && wifi_control_data->set_carddetect ) { 120 wifi_control_data->set_carddetect(on); 121 } 122 return 0; 123 } 124 125 int wifi_set_power( int on, unsigned long msec ) 126 { 127 /* printk("%s = %d\n", __FUNCTION__, on); */ 128 if( wifi_control_data && wifi_control_data->set_power ) { 129 wifi_control_data->set_power(on); 130 } 131 else { 132 gpio_set_value(PMENA_GPIO, on); 133 } 134 if( msec ) 135 mdelay(msec); 136 return 0; 137 } 138 139 int wifi_set_reset( int on, unsigned long msec ) 140 { 141 /* printk("%s = %d\n", __FUNCTION__, on); */ 142 if( wifi_control_data && wifi_control_data->set_reset ) { 143 wifi_control_data->set_reset(on); 144 } 145 if( msec ) 146 mdelay(msec); 147 return 0; 148 } 149 150 /*----------------------------------------------------------------------------- 151 Routine Name: hPlatform_hardResetTnetw 152 Routine Description: set the GPIO to low after awaking the TNET from ELP. 153 Arguments: None 154 Return Value: 0 - Ok 155 -----------------------------------------------------------------------------*/ 156 157 int hPlatform_hardResetTnetw( void ) 158 { 159 int err; 160 161 /* Turn power OFF */ 162 if ((err = wifi_set_power(0, 15)) == 0) { 163 /* Turn power ON*/ 164 err = wifi_set_power(1, 70); 165 } 166 return err; 167 } /* hPlatform_hardResetTnetw() */ 168 169 /* Turn device power off */ 170 int hPlatform_DevicePowerOff( void ) 171 { 172 int err; 173 174 err = wifi_set_power(0, 15); 175 return err; 176 } 177 178 179 /* Turn device power off according to a given delay */ 180 int hPlatform_DevicePowerOffSetLongerDelay(void) 181 { 182 int err; 183 184 err = wifi_set_power(0, SDIO_ATTEMPT_LONGER_DELAY_LINUX); 185 186 return err; 187 } 188 189 /* Turn device power on */ 190 int hPlatform_DevicePowerOn( void ) 191 { 192 int err; 193 194 wifi_set_power(1, 15); /* Fixed power sequence */ 195 wifi_set_power(0, 1); 196 /* Should not be changed, 50 msec cause failures */ 197 err = wifi_set_power(1, 70); 198 return err; 199 } 200 201 /*---------------------------------------------------------------------------*/ 202 203 int hPlatform_Wlan_Hardware_Init(void *tnet_drv) 204 { 205 TWlanDrvIfObj *drv = tnet_drv; 206 207 printk("%s\n", __FUNCTION__); 208 wifi_add_dev(); 209 if (wifi_irqres) { 210 drv->irq = wifi_irqres->start; 211 drv->irq_flags = wifi_irqres->flags & IRQF_TRIGGER_MASK; 212 } 213 else { 214 drv->irq = TNETW_IRQ; 215 drv->irq_flags = (unsigned long)IRQF_TRIGGER_FALLING; 216 } 217 return 0; 218 } 219 220 /*----------------------------------------------------------------------------- 221 222 Routine Name: 223 224 InitInterrupt 225 226 Routine Description: 227 228 this function init the interrupt to the Wlan ISR routine. 229 230 Arguments: 231 232 tnet_drv - Golbal Tnet driver pointer. 233 234 Return Value: 235 236 status 237 238 -----------------------------------------------------------------------------*/ 239 240 int hPlatform_initInterrupt( void *tnet_drv, void* handle_add ) 241 { 242 TWlanDrvIfObj *drv = tnet_drv; 243 int rc; 244 245 if (drv->irq == 0 || handle_add == NULL) 246 { 247 print_err("hPlatform_initInterrupt() bad param drv->irq=%d handle_add=0x%x !!!\n",drv->irq,(int)handle_add); 248 return -EINVAL; 249 } 250 printk("drv->irq = %u, %lx\n", drv->irq, drv->irq_flags); 251 if ((rc = request_irq(drv->irq, handle_add, drv->irq_flags, drv->netdev->name, drv))) 252 { 253 print_err("TIWLAN: Failed to register interrupt handler\n"); 254 return rc; 255 } 256 set_irq_wake(drv->irq, 1); 257 return rc; 258 259 } /* hPlatform_initInterrupt() */ 260 261 /*--------------------------------------------------------------------------------------*/ 262 263 void hPlatform_freeInterrupt( void *tnet_drv ) 264 { 265 TWlanDrvIfObj *drv = tnet_drv; 266 267 set_irq_wake(drv->irq, 0); 268 free_irq(drv->irq, drv); 269 } 270 271 /**************************************************************************************** 272 * hPlatform_hwGetRegistersAddr() 273 **************************************************************************************** 274 DESCRIPTION: 275 276 ARGUMENTS: 277 278 RETURN: 279 280 NOTES: 281 *****************************************************************************************/ 282 void *hPlatform_hwGetRegistersAddr(TI_HANDLE OsContext) 283 { 284 return (void *)OS_API_REG_ADDR; 285 } 286 287 /**************************************************************************************** 288 * hPlatform_hwGetMemoryAddr() 289 **************************************************************************************** 290 DESCRIPTION: 291 292 ARGUMENTS: 293 294 RETURN: 295 296 NOTES: 297 *****************************************************************************************/ 298 void *hPlatform_hwGetMemoryAddr(TI_HANDLE OsContext) 299 { 300 return (void *)OS_API_MEM_ADDR; 301 } 302 303 304 void hPlatform_Wlan_Hardware_DeInit(void) 305 { 306 wifi_del_dev(); 307 } 308