1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 2014 Redpine Signals Inc.
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Permission to use, copy, modify, and/or distribute this software for any
5*4882a593Smuzhiyun * purpose with or without fee is hereby granted, provided that the above
6*4882a593Smuzhiyun * copyright notice and this permission notice appear in all copies.
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*4882a593Smuzhiyun * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*4882a593Smuzhiyun * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*4882a593Smuzhiyun * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*4882a593Smuzhiyun * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*4882a593Smuzhiyun * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*4882a593Smuzhiyun * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun */
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <linux/module.h>
19*4882a593Smuzhiyun #include "rsi_sdio.h"
20*4882a593Smuzhiyun #include "rsi_common.h"
21*4882a593Smuzhiyun #include "rsi_coex.h"
22*4882a593Smuzhiyun #include "rsi_hal.h"
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun /* Default operating mode is wlan STA + BT */
25*4882a593Smuzhiyun static u16 dev_oper_mode = DEV_OPMODE_STA_BT_DUAL;
26*4882a593Smuzhiyun module_param(dev_oper_mode, ushort, 0444);
27*4882a593Smuzhiyun MODULE_PARM_DESC(dev_oper_mode, DEV_OPMODE_PARAM_DESC);
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun /**
30*4882a593Smuzhiyun * rsi_sdio_set_cmd52_arg() - This function prepares cmd 52 read/write arg.
31*4882a593Smuzhiyun * @rw: Read/write
32*4882a593Smuzhiyun * @func: function number
33*4882a593Smuzhiyun * @raw: indicates whether to perform read after write
34*4882a593Smuzhiyun * @address: address to which to read/write
35*4882a593Smuzhiyun * @writedata: data to write
36*4882a593Smuzhiyun *
37*4882a593Smuzhiyun * Return: argument
38*4882a593Smuzhiyun */
rsi_sdio_set_cmd52_arg(bool rw,u8 func,u8 raw,u32 address,u8 writedata)39*4882a593Smuzhiyun static u32 rsi_sdio_set_cmd52_arg(bool rw,
40*4882a593Smuzhiyun u8 func,
41*4882a593Smuzhiyun u8 raw,
42*4882a593Smuzhiyun u32 address,
43*4882a593Smuzhiyun u8 writedata)
44*4882a593Smuzhiyun {
45*4882a593Smuzhiyun return ((rw & 1) << 31) | ((func & 0x7) << 28) |
46*4882a593Smuzhiyun ((raw & 1) << 27) | (1 << 26) |
47*4882a593Smuzhiyun ((address & 0x1FFFF) << 9) | (1 << 8) |
48*4882a593Smuzhiyun (writedata & 0xFF);
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun /**
52*4882a593Smuzhiyun * rsi_cmd52writebyte() - This function issues cmd52 byte write onto the card.
53*4882a593Smuzhiyun * @card: Pointer to the mmc_card.
54*4882a593Smuzhiyun * @address: Address to write.
55*4882a593Smuzhiyun * @byte: Data to write.
56*4882a593Smuzhiyun *
57*4882a593Smuzhiyun * Return: Write status.
58*4882a593Smuzhiyun */
rsi_cmd52writebyte(struct mmc_card * card,u32 address,u8 byte)59*4882a593Smuzhiyun static int rsi_cmd52writebyte(struct mmc_card *card,
60*4882a593Smuzhiyun u32 address,
61*4882a593Smuzhiyun u8 byte)
62*4882a593Smuzhiyun {
63*4882a593Smuzhiyun struct mmc_command io_cmd;
64*4882a593Smuzhiyun u32 arg;
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun memset(&io_cmd, 0, sizeof(io_cmd));
67*4882a593Smuzhiyun arg = rsi_sdio_set_cmd52_arg(1, 0, 0, address, byte);
68*4882a593Smuzhiyun io_cmd.opcode = SD_IO_RW_DIRECT;
69*4882a593Smuzhiyun io_cmd.arg = arg;
70*4882a593Smuzhiyun io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun return mmc_wait_for_cmd(card->host, &io_cmd, 0);
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun /**
76*4882a593Smuzhiyun * rsi_cmd52readbyte() - This function issues cmd52 byte read onto the card.
77*4882a593Smuzhiyun * @card: Pointer to the mmc_card.
78*4882a593Smuzhiyun * @address: Address to read from.
79*4882a593Smuzhiyun * @byte: Variable to store read value.
80*4882a593Smuzhiyun *
81*4882a593Smuzhiyun * Return: Read status.
82*4882a593Smuzhiyun */
rsi_cmd52readbyte(struct mmc_card * card,u32 address,u8 * byte)83*4882a593Smuzhiyun static int rsi_cmd52readbyte(struct mmc_card *card,
84*4882a593Smuzhiyun u32 address,
85*4882a593Smuzhiyun u8 *byte)
86*4882a593Smuzhiyun {
87*4882a593Smuzhiyun struct mmc_command io_cmd;
88*4882a593Smuzhiyun u32 arg;
89*4882a593Smuzhiyun int err;
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun memset(&io_cmd, 0, sizeof(io_cmd));
92*4882a593Smuzhiyun arg = rsi_sdio_set_cmd52_arg(0, 0, 0, address, 0);
93*4882a593Smuzhiyun io_cmd.opcode = SD_IO_RW_DIRECT;
94*4882a593Smuzhiyun io_cmd.arg = arg;
95*4882a593Smuzhiyun io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun err = mmc_wait_for_cmd(card->host, &io_cmd, 0);
98*4882a593Smuzhiyun if ((!err) && (byte))
99*4882a593Smuzhiyun *byte = io_cmd.resp[0] & 0xFF;
100*4882a593Smuzhiyun return err;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun /**
104*4882a593Smuzhiyun * rsi_issue_sdiocommand() - This function issues sdio commands.
105*4882a593Smuzhiyun * @func: Pointer to the sdio_func structure.
106*4882a593Smuzhiyun * @opcode: Opcode value.
107*4882a593Smuzhiyun * @arg: Arguments to pass.
108*4882a593Smuzhiyun * @flags: Flags which are set.
109*4882a593Smuzhiyun * @resp: Pointer to store response.
110*4882a593Smuzhiyun *
111*4882a593Smuzhiyun * Return: err: command status as 0 or -1.
112*4882a593Smuzhiyun */
rsi_issue_sdiocommand(struct sdio_func * func,u32 opcode,u32 arg,u32 flags,u32 * resp)113*4882a593Smuzhiyun static int rsi_issue_sdiocommand(struct sdio_func *func,
114*4882a593Smuzhiyun u32 opcode,
115*4882a593Smuzhiyun u32 arg,
116*4882a593Smuzhiyun u32 flags,
117*4882a593Smuzhiyun u32 *resp)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun struct mmc_command cmd;
120*4882a593Smuzhiyun struct mmc_host *host;
121*4882a593Smuzhiyun int err;
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun host = func->card->host;
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun memset(&cmd, 0, sizeof(struct mmc_command));
126*4882a593Smuzhiyun cmd.opcode = opcode;
127*4882a593Smuzhiyun cmd.arg = arg;
128*4882a593Smuzhiyun cmd.flags = flags;
129*4882a593Smuzhiyun err = mmc_wait_for_cmd(host, &cmd, 3);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun if ((!err) && (resp))
132*4882a593Smuzhiyun *resp = cmd.resp[0];
133*4882a593Smuzhiyun
134*4882a593Smuzhiyun return err;
135*4882a593Smuzhiyun }
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun /**
138*4882a593Smuzhiyun * rsi_handle_interrupt() - This function is called upon the occurrence
139*4882a593Smuzhiyun * of an interrupt.
140*4882a593Smuzhiyun * @function: Pointer to the sdio_func structure.
141*4882a593Smuzhiyun *
142*4882a593Smuzhiyun * Return: None.
143*4882a593Smuzhiyun */
rsi_handle_interrupt(struct sdio_func * function)144*4882a593Smuzhiyun static void rsi_handle_interrupt(struct sdio_func *function)
145*4882a593Smuzhiyun {
146*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(function);
147*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
148*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun if (adapter->priv->fsm_state == FSM_FW_NOT_LOADED)
151*4882a593Smuzhiyun return;
152*4882a593Smuzhiyun
153*4882a593Smuzhiyun rsi_set_event(&dev->rx_thread.event);
154*4882a593Smuzhiyun }
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun /**
157*4882a593Smuzhiyun * rsi_reset_card() - This function resets and re-initializes the card.
158*4882a593Smuzhiyun * @pfunction: Pointer to the sdio_func structure.
159*4882a593Smuzhiyun *
160*4882a593Smuzhiyun * Return: None.
161*4882a593Smuzhiyun */
rsi_reset_card(struct sdio_func * pfunction)162*4882a593Smuzhiyun static void rsi_reset_card(struct sdio_func *pfunction)
163*4882a593Smuzhiyun {
164*4882a593Smuzhiyun int ret = 0;
165*4882a593Smuzhiyun int err;
166*4882a593Smuzhiyun struct mmc_card *card = pfunction->card;
167*4882a593Smuzhiyun struct mmc_host *host = card->host;
168*4882a593Smuzhiyun u8 cmd52_resp;
169*4882a593Smuzhiyun u32 clock, resp, i;
170*4882a593Smuzhiyun u16 rca;
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun /* Reset 9110 chip */
173*4882a593Smuzhiyun ret = rsi_cmd52writebyte(pfunction->card,
174*4882a593Smuzhiyun SDIO_CCCR_ABORT,
175*4882a593Smuzhiyun (1 << 3));
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun /* Card will not send any response as it is getting reset immediately
178*4882a593Smuzhiyun * Hence expect a timeout status from host controller
179*4882a593Smuzhiyun */
180*4882a593Smuzhiyun if (ret != -ETIMEDOUT)
181*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Reset failed : %d\n", __func__, ret);
182*4882a593Smuzhiyun
183*4882a593Smuzhiyun /* Wait for few milli seconds to get rid of residue charges if any */
184*4882a593Smuzhiyun msleep(20);
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun /* Initialize the SDIO card */
187*4882a593Smuzhiyun host->ios.chip_select = MMC_CS_DONTCARE;
188*4882a593Smuzhiyun host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
189*4882a593Smuzhiyun host->ios.power_mode = MMC_POWER_UP;
190*4882a593Smuzhiyun host->ios.bus_width = MMC_BUS_WIDTH_1;
191*4882a593Smuzhiyun host->ios.timing = MMC_TIMING_LEGACY;
192*4882a593Smuzhiyun host->ops->set_ios(host, &host->ios);
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun /*
195*4882a593Smuzhiyun * This delay should be sufficient to allow the power supply
196*4882a593Smuzhiyun * to reach the minimum voltage.
197*4882a593Smuzhiyun */
198*4882a593Smuzhiyun msleep(20);
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun host->ios.clock = host->f_min;
201*4882a593Smuzhiyun host->ios.power_mode = MMC_POWER_ON;
202*4882a593Smuzhiyun host->ops->set_ios(host, &host->ios);
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun /*
205*4882a593Smuzhiyun * This delay must be at least 74 clock sizes, or 1 ms, or the
206*4882a593Smuzhiyun * time required to reach a stable voltage.
207*4882a593Smuzhiyun */
208*4882a593Smuzhiyun msleep(20);
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun /* Issue CMD0. Goto idle state */
211*4882a593Smuzhiyun host->ios.chip_select = MMC_CS_HIGH;
212*4882a593Smuzhiyun host->ops->set_ios(host, &host->ios);
213*4882a593Smuzhiyun msleep(20);
214*4882a593Smuzhiyun err = rsi_issue_sdiocommand(pfunction,
215*4882a593Smuzhiyun MMC_GO_IDLE_STATE,
216*4882a593Smuzhiyun 0,
217*4882a593Smuzhiyun (MMC_RSP_NONE | MMC_CMD_BC),
218*4882a593Smuzhiyun NULL);
219*4882a593Smuzhiyun host->ios.chip_select = MMC_CS_DONTCARE;
220*4882a593Smuzhiyun host->ops->set_ios(host, &host->ios);
221*4882a593Smuzhiyun msleep(20);
222*4882a593Smuzhiyun host->use_spi_crc = 0;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun if (err)
225*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: CMD0 failed : %d\n", __func__, err);
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun /* Issue CMD5, arg = 0 */
228*4882a593Smuzhiyun err = rsi_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND, 0,
229*4882a593Smuzhiyun (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
230*4882a593Smuzhiyun if (err)
231*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
232*4882a593Smuzhiyun __func__, err);
233*4882a593Smuzhiyun card->ocr = resp;
234*4882a593Smuzhiyun /* Issue CMD5, arg = ocr. Wait till card is ready */
235*4882a593Smuzhiyun for (i = 0; i < 100; i++) {
236*4882a593Smuzhiyun err = rsi_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND,
237*4882a593Smuzhiyun card->ocr,
238*4882a593Smuzhiyun (MMC_RSP_R4 | MMC_CMD_BCR), &resp);
239*4882a593Smuzhiyun if (err) {
240*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n",
241*4882a593Smuzhiyun __func__, err);
242*4882a593Smuzhiyun break;
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun if (resp & MMC_CARD_BUSY)
246*4882a593Smuzhiyun break;
247*4882a593Smuzhiyun msleep(20);
248*4882a593Smuzhiyun }
249*4882a593Smuzhiyun
250*4882a593Smuzhiyun if ((i == 100) || (err)) {
251*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: card in not ready : %d %d\n",
252*4882a593Smuzhiyun __func__, i, err);
253*4882a593Smuzhiyun return;
254*4882a593Smuzhiyun }
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun /* Issue CMD3, get RCA */
257*4882a593Smuzhiyun err = rsi_issue_sdiocommand(pfunction,
258*4882a593Smuzhiyun SD_SEND_RELATIVE_ADDR,
259*4882a593Smuzhiyun 0,
260*4882a593Smuzhiyun (MMC_RSP_R6 | MMC_CMD_BCR),
261*4882a593Smuzhiyun &resp);
262*4882a593Smuzhiyun if (err) {
263*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: CMD3 failed : %d\n", __func__, err);
264*4882a593Smuzhiyun return;
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun rca = resp >> 16;
267*4882a593Smuzhiyun host->ios.bus_mode = MMC_BUSMODE_PUSHPULL;
268*4882a593Smuzhiyun host->ops->set_ios(host, &host->ios);
269*4882a593Smuzhiyun
270*4882a593Smuzhiyun /* Issue CMD7, select card */
271*4882a593Smuzhiyun err = rsi_issue_sdiocommand(pfunction,
272*4882a593Smuzhiyun MMC_SELECT_CARD,
273*4882a593Smuzhiyun (rca << 16),
274*4882a593Smuzhiyun (MMC_RSP_R1 | MMC_CMD_AC),
275*4882a593Smuzhiyun NULL);
276*4882a593Smuzhiyun if (err) {
277*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: CMD7 failed : %d\n", __func__, err);
278*4882a593Smuzhiyun return;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun /* Enable high speed */
282*4882a593Smuzhiyun if (card->host->caps & MMC_CAP_SD_HIGHSPEED) {
283*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Set high speed mode\n", __func__);
284*4882a593Smuzhiyun err = rsi_cmd52readbyte(card, SDIO_CCCR_SPEED, &cmd52_resp);
285*4882a593Smuzhiyun if (err) {
286*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: CCCR speed reg read failed: %d\n",
287*4882a593Smuzhiyun __func__, err);
288*4882a593Smuzhiyun } else {
289*4882a593Smuzhiyun err = rsi_cmd52writebyte(card,
290*4882a593Smuzhiyun SDIO_CCCR_SPEED,
291*4882a593Smuzhiyun (cmd52_resp | SDIO_SPEED_EHS));
292*4882a593Smuzhiyun if (err) {
293*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
294*4882a593Smuzhiyun "%s: CCR speed regwrite failed %d\n",
295*4882a593Smuzhiyun __func__, err);
296*4882a593Smuzhiyun return;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun host->ios.timing = MMC_TIMING_SD_HS;
299*4882a593Smuzhiyun host->ops->set_ios(host, &host->ios);
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun /* Set clock */
304*4882a593Smuzhiyun if (mmc_card_hs(card))
305*4882a593Smuzhiyun clock = 50000000;
306*4882a593Smuzhiyun else
307*4882a593Smuzhiyun clock = card->cis.max_dtr;
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun if (clock > host->f_max)
310*4882a593Smuzhiyun clock = host->f_max;
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun host->ios.clock = clock;
313*4882a593Smuzhiyun host->ops->set_ios(host, &host->ios);
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun if (card->host->caps & MMC_CAP_4_BIT_DATA) {
316*4882a593Smuzhiyun /* CMD52: Set bus width & disable card detect resistor */
317*4882a593Smuzhiyun err = rsi_cmd52writebyte(card,
318*4882a593Smuzhiyun SDIO_CCCR_IF,
319*4882a593Smuzhiyun (SDIO_BUS_CD_DISABLE |
320*4882a593Smuzhiyun SDIO_BUS_WIDTH_4BIT));
321*4882a593Smuzhiyun if (err) {
322*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Set bus mode failed : %d\n",
323*4882a593Smuzhiyun __func__, err);
324*4882a593Smuzhiyun return;
325*4882a593Smuzhiyun }
326*4882a593Smuzhiyun host->ios.bus_width = MMC_BUS_WIDTH_4;
327*4882a593Smuzhiyun host->ops->set_ios(host, &host->ios);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun }
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun /**
332*4882a593Smuzhiyun * rsi_setclock() - This function sets the clock frequency.
333*4882a593Smuzhiyun * @adapter: Pointer to the adapter structure.
334*4882a593Smuzhiyun * @freq: Clock frequency.
335*4882a593Smuzhiyun *
336*4882a593Smuzhiyun * Return: None.
337*4882a593Smuzhiyun */
rsi_setclock(struct rsi_hw * adapter,u32 freq)338*4882a593Smuzhiyun static void rsi_setclock(struct rsi_hw *adapter, u32 freq)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
341*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
342*4882a593Smuzhiyun struct mmc_host *host = dev->pfunction->card->host;
343*4882a593Smuzhiyun u32 clock;
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun clock = freq * 1000;
346*4882a593Smuzhiyun if (clock > host->f_max)
347*4882a593Smuzhiyun clock = host->f_max;
348*4882a593Smuzhiyun host->ios.clock = clock;
349*4882a593Smuzhiyun host->ops->set_ios(host, &host->ios);
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun /**
353*4882a593Smuzhiyun * rsi_setblocklength() - This function sets the host block length.
354*4882a593Smuzhiyun * @adapter: Pointer to the adapter structure.
355*4882a593Smuzhiyun * @length: Block length to be set.
356*4882a593Smuzhiyun *
357*4882a593Smuzhiyun * Return: status: 0 on success, -1 on failure.
358*4882a593Smuzhiyun */
rsi_setblocklength(struct rsi_hw * adapter,u32 length)359*4882a593Smuzhiyun static int rsi_setblocklength(struct rsi_hw *adapter, u32 length)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
362*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
363*4882a593Smuzhiyun int status;
364*4882a593Smuzhiyun rsi_dbg(INIT_ZONE, "%s: Setting the block length\n", __func__);
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun status = sdio_set_block_size(dev->pfunction, length);
367*4882a593Smuzhiyun dev->pfunction->max_blksize = 256;
368*4882a593Smuzhiyun adapter->block_size = dev->pfunction->max_blksize;
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun rsi_dbg(INFO_ZONE,
371*4882a593Smuzhiyun "%s: Operational blk length is %d\n", __func__, length);
372*4882a593Smuzhiyun return status;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun /**
376*4882a593Smuzhiyun * rsi_setupcard() - This function queries and sets the card's features.
377*4882a593Smuzhiyun * @adapter: Pointer to the adapter structure.
378*4882a593Smuzhiyun *
379*4882a593Smuzhiyun * Return: status: 0 on success, -1 on failure.
380*4882a593Smuzhiyun */
rsi_setupcard(struct rsi_hw * adapter)381*4882a593Smuzhiyun static int rsi_setupcard(struct rsi_hw *adapter)
382*4882a593Smuzhiyun {
383*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
384*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
385*4882a593Smuzhiyun int status = 0;
386*4882a593Smuzhiyun
387*4882a593Smuzhiyun rsi_setclock(adapter, 50000);
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun dev->tx_blk_size = 256;
390*4882a593Smuzhiyun status = rsi_setblocklength(adapter, dev->tx_blk_size);
391*4882a593Smuzhiyun if (status)
392*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
393*4882a593Smuzhiyun "%s: Unable to set block length\n", __func__);
394*4882a593Smuzhiyun return status;
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun /**
398*4882a593Smuzhiyun * rsi_sdio_read_register() - This function reads one byte of information
399*4882a593Smuzhiyun * from a register.
400*4882a593Smuzhiyun * @adapter: Pointer to the adapter structure.
401*4882a593Smuzhiyun * @addr: Address of the register.
402*4882a593Smuzhiyun * @data: Pointer to the data that stores the data read.
403*4882a593Smuzhiyun *
404*4882a593Smuzhiyun * Return: 0 on success, -1 on failure.
405*4882a593Smuzhiyun */
rsi_sdio_read_register(struct rsi_hw * adapter,u32 addr,u8 * data)406*4882a593Smuzhiyun int rsi_sdio_read_register(struct rsi_hw *adapter,
407*4882a593Smuzhiyun u32 addr,
408*4882a593Smuzhiyun u8 *data)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
411*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
412*4882a593Smuzhiyun u8 fun_num = 0;
413*4882a593Smuzhiyun int status;
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun if (likely(dev->sdio_irq_task != current))
416*4882a593Smuzhiyun sdio_claim_host(dev->pfunction);
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun if (fun_num == 0)
419*4882a593Smuzhiyun *data = sdio_f0_readb(dev->pfunction, addr, &status);
420*4882a593Smuzhiyun else
421*4882a593Smuzhiyun *data = sdio_readb(dev->pfunction, addr, &status);
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun if (likely(dev->sdio_irq_task != current))
424*4882a593Smuzhiyun sdio_release_host(dev->pfunction);
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun return status;
427*4882a593Smuzhiyun }
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun /**
430*4882a593Smuzhiyun * rsi_sdio_write_register() - This function writes one byte of information
431*4882a593Smuzhiyun * into a register.
432*4882a593Smuzhiyun * @adapter: Pointer to the adapter structure.
433*4882a593Smuzhiyun * @function: Function Number.
434*4882a593Smuzhiyun * @addr: Address of the register.
435*4882a593Smuzhiyun * @data: Pointer to the data tha has to be written.
436*4882a593Smuzhiyun *
437*4882a593Smuzhiyun * Return: 0 on success, -1 on failure.
438*4882a593Smuzhiyun */
rsi_sdio_write_register(struct rsi_hw * adapter,u8 function,u32 addr,u8 * data)439*4882a593Smuzhiyun int rsi_sdio_write_register(struct rsi_hw *adapter,
440*4882a593Smuzhiyun u8 function,
441*4882a593Smuzhiyun u32 addr,
442*4882a593Smuzhiyun u8 *data)
443*4882a593Smuzhiyun {
444*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
445*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
446*4882a593Smuzhiyun int status = 0;
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun if (likely(dev->sdio_irq_task != current))
449*4882a593Smuzhiyun sdio_claim_host(dev->pfunction);
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun if (function == 0)
452*4882a593Smuzhiyun sdio_f0_writeb(dev->pfunction, *data, addr, &status);
453*4882a593Smuzhiyun else
454*4882a593Smuzhiyun sdio_writeb(dev->pfunction, *data, addr, &status);
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun if (likely(dev->sdio_irq_task != current))
457*4882a593Smuzhiyun sdio_release_host(dev->pfunction);
458*4882a593Smuzhiyun
459*4882a593Smuzhiyun return status;
460*4882a593Smuzhiyun }
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun /**
463*4882a593Smuzhiyun * rsi_sdio_ack_intr() - This function acks the interrupt received.
464*4882a593Smuzhiyun * @adapter: Pointer to the adapter structure.
465*4882a593Smuzhiyun * @int_bit: Interrupt bit to write into register.
466*4882a593Smuzhiyun *
467*4882a593Smuzhiyun * Return: None.
468*4882a593Smuzhiyun */
rsi_sdio_ack_intr(struct rsi_hw * adapter,u8 int_bit)469*4882a593Smuzhiyun void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit)
470*4882a593Smuzhiyun {
471*4882a593Smuzhiyun int status;
472*4882a593Smuzhiyun status = rsi_sdio_write_register(adapter,
473*4882a593Smuzhiyun 1,
474*4882a593Smuzhiyun (SDIO_FUN1_INTR_CLR_REG |
475*4882a593Smuzhiyun RSI_SD_REQUEST_MASTER),
476*4882a593Smuzhiyun &int_bit);
477*4882a593Smuzhiyun if (status)
478*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: unable to send ack\n", __func__);
479*4882a593Smuzhiyun }
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun /**
484*4882a593Smuzhiyun * rsi_sdio_read_register_multiple() - This function read multiple bytes of
485*4882a593Smuzhiyun * information from the SD card.
486*4882a593Smuzhiyun * @adapter: Pointer to the adapter structure.
487*4882a593Smuzhiyun * @addr: Address of the register.
488*4882a593Smuzhiyun * @count: Number of multiple bytes to be read.
489*4882a593Smuzhiyun * @data: Pointer to the read data.
490*4882a593Smuzhiyun *
491*4882a593Smuzhiyun * Return: 0 on success, -1 on failure.
492*4882a593Smuzhiyun */
rsi_sdio_read_register_multiple(struct rsi_hw * adapter,u32 addr,u8 * data,u16 count)493*4882a593Smuzhiyun static int rsi_sdio_read_register_multiple(struct rsi_hw *adapter,
494*4882a593Smuzhiyun u32 addr,
495*4882a593Smuzhiyun u8 *data,
496*4882a593Smuzhiyun u16 count)
497*4882a593Smuzhiyun {
498*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
499*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
500*4882a593Smuzhiyun u32 status;
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun if (likely(dev->sdio_irq_task != current))
503*4882a593Smuzhiyun sdio_claim_host(dev->pfunction);
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun status = sdio_readsb(dev->pfunction, data, addr, count);
506*4882a593Smuzhiyun
507*4882a593Smuzhiyun if (likely(dev->sdio_irq_task != current))
508*4882a593Smuzhiyun sdio_release_host(dev->pfunction);
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun if (status != 0)
511*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 read failed\n", __func__);
512*4882a593Smuzhiyun return status;
513*4882a593Smuzhiyun }
514*4882a593Smuzhiyun
515*4882a593Smuzhiyun /**
516*4882a593Smuzhiyun * rsi_sdio_write_register_multiple() - This function writes multiple bytes of
517*4882a593Smuzhiyun * information to the SD card.
518*4882a593Smuzhiyun * @adapter: Pointer to the adapter structure.
519*4882a593Smuzhiyun * @addr: Address of the register.
520*4882a593Smuzhiyun * @data: Pointer to the data that has to be written.
521*4882a593Smuzhiyun * @count: Number of multiple bytes to be written.
522*4882a593Smuzhiyun *
523*4882a593Smuzhiyun * Return: 0 on success, -1 on failure.
524*4882a593Smuzhiyun */
rsi_sdio_write_register_multiple(struct rsi_hw * adapter,u32 addr,u8 * data,u16 count)525*4882a593Smuzhiyun int rsi_sdio_write_register_multiple(struct rsi_hw *adapter,
526*4882a593Smuzhiyun u32 addr,
527*4882a593Smuzhiyun u8 *data,
528*4882a593Smuzhiyun u16 count)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
531*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
532*4882a593Smuzhiyun int status;
533*4882a593Smuzhiyun
534*4882a593Smuzhiyun if (dev->write_fail > 1) {
535*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Stopping card writes\n", __func__);
536*4882a593Smuzhiyun return 0;
537*4882a593Smuzhiyun } else if (dev->write_fail == 1) {
538*4882a593Smuzhiyun /**
539*4882a593Smuzhiyun * Assuming it is a CRC failure, we want to allow another
540*4882a593Smuzhiyun * card write
541*4882a593Smuzhiyun */
542*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Continue card writes\n", __func__);
543*4882a593Smuzhiyun dev->write_fail++;
544*4882a593Smuzhiyun }
545*4882a593Smuzhiyun
546*4882a593Smuzhiyun if (likely(dev->sdio_irq_task != current))
547*4882a593Smuzhiyun sdio_claim_host(dev->pfunction);
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun status = sdio_writesb(dev->pfunction, addr, data, count);
550*4882a593Smuzhiyun
551*4882a593Smuzhiyun if (likely(dev->sdio_irq_task != current))
552*4882a593Smuzhiyun sdio_release_host(dev->pfunction);
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun if (status) {
555*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 write failed %d\n",
556*4882a593Smuzhiyun __func__, status);
557*4882a593Smuzhiyun dev->write_fail = 2;
558*4882a593Smuzhiyun } else {
559*4882a593Smuzhiyun memcpy(dev->prev_desc, data, FRAME_DESC_SZ);
560*4882a593Smuzhiyun }
561*4882a593Smuzhiyun return status;
562*4882a593Smuzhiyun }
563*4882a593Smuzhiyun
rsi_sdio_load_data_master_write(struct rsi_hw * adapter,u32 base_address,u32 instructions_sz,u16 block_size,u8 * ta_firmware)564*4882a593Smuzhiyun static int rsi_sdio_load_data_master_write(struct rsi_hw *adapter,
565*4882a593Smuzhiyun u32 base_address,
566*4882a593Smuzhiyun u32 instructions_sz,
567*4882a593Smuzhiyun u16 block_size,
568*4882a593Smuzhiyun u8 *ta_firmware)
569*4882a593Smuzhiyun {
570*4882a593Smuzhiyun u32 num_blocks, offset, i;
571*4882a593Smuzhiyun u16 msb_address, lsb_address;
572*4882a593Smuzhiyun u8 *temp_buf;
573*4882a593Smuzhiyun int status;
574*4882a593Smuzhiyun
575*4882a593Smuzhiyun num_blocks = instructions_sz / block_size;
576*4882a593Smuzhiyun msb_address = base_address >> 16;
577*4882a593Smuzhiyun
578*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "ins_size: %d, num_blocks: %d\n",
579*4882a593Smuzhiyun instructions_sz, num_blocks);
580*4882a593Smuzhiyun
581*4882a593Smuzhiyun temp_buf = kmalloc(block_size, GFP_KERNEL);
582*4882a593Smuzhiyun if (!temp_buf)
583*4882a593Smuzhiyun return -ENOMEM;
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun /* Loading DM ms word in the sdio slave */
586*4882a593Smuzhiyun status = rsi_sdio_master_access_msword(adapter, msb_address);
587*4882a593Smuzhiyun if (status < 0) {
588*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
589*4882a593Smuzhiyun goto out_free;
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun for (offset = 0, i = 0; i < num_blocks; i++, offset += block_size) {
593*4882a593Smuzhiyun memcpy(temp_buf, ta_firmware + offset, block_size);
594*4882a593Smuzhiyun lsb_address = (u16)base_address;
595*4882a593Smuzhiyun status = rsi_sdio_write_register_multiple
596*4882a593Smuzhiyun (adapter,
597*4882a593Smuzhiyun lsb_address | RSI_SD_REQUEST_MASTER,
598*4882a593Smuzhiyun temp_buf, block_size);
599*4882a593Smuzhiyun if (status < 0) {
600*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: failed to write\n", __func__);
601*4882a593Smuzhiyun goto out_free;
602*4882a593Smuzhiyun }
603*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "%s: loading block: %d\n", __func__, i);
604*4882a593Smuzhiyun base_address += block_size;
605*4882a593Smuzhiyun
606*4882a593Smuzhiyun if ((base_address >> 16) != msb_address) {
607*4882a593Smuzhiyun msb_address += 1;
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun /* Loading DM ms word in the sdio slave */
610*4882a593Smuzhiyun status = rsi_sdio_master_access_msword(adapter,
611*4882a593Smuzhiyun msb_address);
612*4882a593Smuzhiyun if (status < 0) {
613*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
614*4882a593Smuzhiyun "%s: Unable to set ms word reg\n",
615*4882a593Smuzhiyun __func__);
616*4882a593Smuzhiyun goto out_free;
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun }
619*4882a593Smuzhiyun }
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun if (instructions_sz % block_size) {
622*4882a593Smuzhiyun memset(temp_buf, 0, block_size);
623*4882a593Smuzhiyun memcpy(temp_buf, ta_firmware + offset,
624*4882a593Smuzhiyun instructions_sz % block_size);
625*4882a593Smuzhiyun lsb_address = (u16)base_address;
626*4882a593Smuzhiyun status = rsi_sdio_write_register_multiple
627*4882a593Smuzhiyun (adapter,
628*4882a593Smuzhiyun lsb_address | RSI_SD_REQUEST_MASTER,
629*4882a593Smuzhiyun temp_buf,
630*4882a593Smuzhiyun instructions_sz % block_size);
631*4882a593Smuzhiyun if (status < 0)
632*4882a593Smuzhiyun goto out_free;
633*4882a593Smuzhiyun rsi_dbg(INFO_ZONE,
634*4882a593Smuzhiyun "Written Last Block in Address 0x%x Successfully\n",
635*4882a593Smuzhiyun offset | RSI_SD_REQUEST_MASTER);
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun status = 0;
639*4882a593Smuzhiyun out_free:
640*4882a593Smuzhiyun kfree(temp_buf);
641*4882a593Smuzhiyun return status;
642*4882a593Smuzhiyun }
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun #define FLASH_SIZE_ADDR 0x04000016
rsi_sdio_master_reg_read(struct rsi_hw * adapter,u32 addr,u32 * read_buf,u16 size)645*4882a593Smuzhiyun static int rsi_sdio_master_reg_read(struct rsi_hw *adapter, u32 addr,
646*4882a593Smuzhiyun u32 *read_buf, u16 size)
647*4882a593Smuzhiyun {
648*4882a593Smuzhiyun u32 addr_on_bus, *data;
649*4882a593Smuzhiyun u16 ms_addr;
650*4882a593Smuzhiyun int status;
651*4882a593Smuzhiyun
652*4882a593Smuzhiyun data = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL);
653*4882a593Smuzhiyun if (!data)
654*4882a593Smuzhiyun return -ENOMEM;
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun ms_addr = (addr >> 16);
657*4882a593Smuzhiyun status = rsi_sdio_master_access_msword(adapter, ms_addr);
658*4882a593Smuzhiyun if (status < 0) {
659*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
660*4882a593Smuzhiyun "%s: Unable to set ms word to common reg\n",
661*4882a593Smuzhiyun __func__);
662*4882a593Smuzhiyun goto err;
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun addr &= 0xFFFF;
665*4882a593Smuzhiyun
666*4882a593Smuzhiyun addr_on_bus = (addr & 0xFF000000);
667*4882a593Smuzhiyun if ((addr_on_bus == (FLASH_SIZE_ADDR & 0xFF000000)) ||
668*4882a593Smuzhiyun (addr_on_bus == 0x0))
669*4882a593Smuzhiyun addr_on_bus = (addr & ~(0x3));
670*4882a593Smuzhiyun else
671*4882a593Smuzhiyun addr_on_bus = addr;
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun /* Bring TA out of reset */
674*4882a593Smuzhiyun status = rsi_sdio_read_register_multiple
675*4882a593Smuzhiyun (adapter,
676*4882a593Smuzhiyun (addr_on_bus | RSI_SD_REQUEST_MASTER),
677*4882a593Smuzhiyun (u8 *)data, 4);
678*4882a593Smuzhiyun if (status < 0) {
679*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: AHB register read failed\n", __func__);
680*4882a593Smuzhiyun goto err;
681*4882a593Smuzhiyun }
682*4882a593Smuzhiyun if (size == 2) {
683*4882a593Smuzhiyun if ((addr & 0x3) == 0)
684*4882a593Smuzhiyun *read_buf = *data;
685*4882a593Smuzhiyun else
686*4882a593Smuzhiyun *read_buf = (*data >> 16);
687*4882a593Smuzhiyun *read_buf = (*read_buf & 0xFFFF);
688*4882a593Smuzhiyun } else if (size == 1) {
689*4882a593Smuzhiyun if ((addr & 0x3) == 0)
690*4882a593Smuzhiyun *read_buf = *data;
691*4882a593Smuzhiyun else if ((addr & 0x3) == 1)
692*4882a593Smuzhiyun *read_buf = (*data >> 8);
693*4882a593Smuzhiyun else if ((addr & 0x3) == 2)
694*4882a593Smuzhiyun *read_buf = (*data >> 16);
695*4882a593Smuzhiyun else
696*4882a593Smuzhiyun *read_buf = (*data >> 24);
697*4882a593Smuzhiyun *read_buf = (*read_buf & 0xFF);
698*4882a593Smuzhiyun } else {
699*4882a593Smuzhiyun *read_buf = *data;
700*4882a593Smuzhiyun }
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun err:
703*4882a593Smuzhiyun kfree(data);
704*4882a593Smuzhiyun return status;
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun
rsi_sdio_master_reg_write(struct rsi_hw * adapter,unsigned long addr,unsigned long data,u16 size)707*4882a593Smuzhiyun static int rsi_sdio_master_reg_write(struct rsi_hw *adapter,
708*4882a593Smuzhiyun unsigned long addr,
709*4882a593Smuzhiyun unsigned long data, u16 size)
710*4882a593Smuzhiyun {
711*4882a593Smuzhiyun unsigned long *data_aligned;
712*4882a593Smuzhiyun int status;
713*4882a593Smuzhiyun
714*4882a593Smuzhiyun data_aligned = kzalloc(RSI_MASTER_REG_BUF_SIZE, GFP_KERNEL);
715*4882a593Smuzhiyun if (!data_aligned)
716*4882a593Smuzhiyun return -ENOMEM;
717*4882a593Smuzhiyun
718*4882a593Smuzhiyun if (size == 2) {
719*4882a593Smuzhiyun *data_aligned = ((data << 16) | (data & 0xFFFF));
720*4882a593Smuzhiyun } else if (size == 1) {
721*4882a593Smuzhiyun u32 temp_data = data & 0xFF;
722*4882a593Smuzhiyun
723*4882a593Smuzhiyun *data_aligned = ((temp_data << 24) | (temp_data << 16) |
724*4882a593Smuzhiyun (temp_data << 8) | temp_data);
725*4882a593Smuzhiyun } else {
726*4882a593Smuzhiyun *data_aligned = data;
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun size = 4;
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun status = rsi_sdio_master_access_msword(adapter, (addr >> 16));
731*4882a593Smuzhiyun if (status < 0) {
732*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
733*4882a593Smuzhiyun "%s: Unable to set ms word to common reg\n",
734*4882a593Smuzhiyun __func__);
735*4882a593Smuzhiyun kfree(data_aligned);
736*4882a593Smuzhiyun return -EIO;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun addr = addr & 0xFFFF;
739*4882a593Smuzhiyun
740*4882a593Smuzhiyun /* Bring TA out of reset */
741*4882a593Smuzhiyun status = rsi_sdio_write_register_multiple
742*4882a593Smuzhiyun (adapter,
743*4882a593Smuzhiyun (addr | RSI_SD_REQUEST_MASTER),
744*4882a593Smuzhiyun (u8 *)data_aligned, size);
745*4882a593Smuzhiyun if (status < 0)
746*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
747*4882a593Smuzhiyun "%s: Unable to do AHB reg write\n", __func__);
748*4882a593Smuzhiyun
749*4882a593Smuzhiyun kfree(data_aligned);
750*4882a593Smuzhiyun return status;
751*4882a593Smuzhiyun }
752*4882a593Smuzhiyun
753*4882a593Smuzhiyun /**
754*4882a593Smuzhiyun * rsi_sdio_host_intf_write_pkt() - This function writes the packet to device.
755*4882a593Smuzhiyun * @adapter: Pointer to the adapter structure.
756*4882a593Smuzhiyun * @pkt: Pointer to the data to be written on to the device.
757*4882a593Smuzhiyun * @len: length of the data to be written on to the device.
758*4882a593Smuzhiyun *
759*4882a593Smuzhiyun * Return: 0 on success, -1 on failure.
760*4882a593Smuzhiyun */
rsi_sdio_host_intf_write_pkt(struct rsi_hw * adapter,u8 * pkt,u32 len)761*4882a593Smuzhiyun static int rsi_sdio_host_intf_write_pkt(struct rsi_hw *adapter,
762*4882a593Smuzhiyun u8 *pkt,
763*4882a593Smuzhiyun u32 len)
764*4882a593Smuzhiyun {
765*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
766*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
767*4882a593Smuzhiyun u32 block_size = dev->tx_blk_size;
768*4882a593Smuzhiyun u32 num_blocks, address, length;
769*4882a593Smuzhiyun u32 queueno;
770*4882a593Smuzhiyun int status;
771*4882a593Smuzhiyun
772*4882a593Smuzhiyun queueno = ((pkt[1] >> 4) & 0xf);
773*4882a593Smuzhiyun if (queueno == RSI_BT_MGMT_Q || queueno == RSI_BT_DATA_Q)
774*4882a593Smuzhiyun queueno = RSI_BT_Q;
775*4882a593Smuzhiyun
776*4882a593Smuzhiyun num_blocks = len / block_size;
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun if (len % block_size)
779*4882a593Smuzhiyun num_blocks++;
780*4882a593Smuzhiyun
781*4882a593Smuzhiyun address = (num_blocks * block_size | (queueno << 12));
782*4882a593Smuzhiyun length = num_blocks * block_size;
783*4882a593Smuzhiyun
784*4882a593Smuzhiyun status = rsi_sdio_write_register_multiple(adapter,
785*4882a593Smuzhiyun address,
786*4882a593Smuzhiyun (u8 *)pkt,
787*4882a593Smuzhiyun length);
788*4882a593Smuzhiyun if (status)
789*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Unable to write onto the card: %d\n",
790*4882a593Smuzhiyun __func__, status);
791*4882a593Smuzhiyun rsi_dbg(DATA_TX_ZONE, "%s: Successfully written onto card\n", __func__);
792*4882a593Smuzhiyun return status;
793*4882a593Smuzhiyun }
794*4882a593Smuzhiyun
795*4882a593Smuzhiyun /**
796*4882a593Smuzhiyun * rsi_sdio_host_intf_read_pkt() - This function reads the packet
797*4882a593Smuzhiyun * from the device.
798*4882a593Smuzhiyun * @adapter: Pointer to the adapter data structure.
799*4882a593Smuzhiyun * @pkt: Pointer to the packet data to be read from the the device.
800*4882a593Smuzhiyun * @length: Length of the data to be read from the device.
801*4882a593Smuzhiyun *
802*4882a593Smuzhiyun * Return: 0 on success, -1 on failure.
803*4882a593Smuzhiyun */
rsi_sdio_host_intf_read_pkt(struct rsi_hw * adapter,u8 * pkt,u32 length)804*4882a593Smuzhiyun int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter,
805*4882a593Smuzhiyun u8 *pkt,
806*4882a593Smuzhiyun u32 length)
807*4882a593Smuzhiyun {
808*4882a593Smuzhiyun int status = -EINVAL;
809*4882a593Smuzhiyun
810*4882a593Smuzhiyun if (!length) {
811*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Pkt size is zero\n", __func__);
812*4882a593Smuzhiyun return status;
813*4882a593Smuzhiyun }
814*4882a593Smuzhiyun
815*4882a593Smuzhiyun status = rsi_sdio_read_register_multiple(adapter,
816*4882a593Smuzhiyun length,
817*4882a593Smuzhiyun (u8 *)pkt,
818*4882a593Smuzhiyun length); /*num of bytes*/
819*4882a593Smuzhiyun
820*4882a593Smuzhiyun if (status)
821*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed to read frame: %d\n", __func__,
822*4882a593Smuzhiyun status);
823*4882a593Smuzhiyun return status;
824*4882a593Smuzhiyun }
825*4882a593Smuzhiyun
826*4882a593Smuzhiyun /**
827*4882a593Smuzhiyun * rsi_init_sdio_interface() - This function does init specific to SDIO.
828*4882a593Smuzhiyun *
829*4882a593Smuzhiyun * @adapter: Pointer to the adapter data structure.
830*4882a593Smuzhiyun * @pfunction: Pointer to the sdio_func structure.
831*4882a593Smuzhiyun *
832*4882a593Smuzhiyun * Return: 0 on success, -1 on failure.
833*4882a593Smuzhiyun */
rsi_init_sdio_interface(struct rsi_hw * adapter,struct sdio_func * pfunction)834*4882a593Smuzhiyun static int rsi_init_sdio_interface(struct rsi_hw *adapter,
835*4882a593Smuzhiyun struct sdio_func *pfunction)
836*4882a593Smuzhiyun {
837*4882a593Smuzhiyun struct rsi_91x_sdiodev *rsi_91x_dev;
838*4882a593Smuzhiyun int status;
839*4882a593Smuzhiyun
840*4882a593Smuzhiyun rsi_91x_dev = kzalloc(sizeof(*rsi_91x_dev), GFP_KERNEL);
841*4882a593Smuzhiyun if (!rsi_91x_dev)
842*4882a593Smuzhiyun return -ENOMEM;
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun adapter->rsi_dev = rsi_91x_dev;
845*4882a593Smuzhiyun
846*4882a593Smuzhiyun sdio_claim_host(pfunction);
847*4882a593Smuzhiyun
848*4882a593Smuzhiyun pfunction->enable_timeout = 100;
849*4882a593Smuzhiyun status = sdio_enable_func(pfunction);
850*4882a593Smuzhiyun if (status) {
851*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed to enable interface\n", __func__);
852*4882a593Smuzhiyun sdio_release_host(pfunction);
853*4882a593Smuzhiyun return status;
854*4882a593Smuzhiyun }
855*4882a593Smuzhiyun
856*4882a593Smuzhiyun rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun rsi_91x_dev->pfunction = pfunction;
859*4882a593Smuzhiyun adapter->device = &pfunction->dev;
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun sdio_set_drvdata(pfunction, adapter);
862*4882a593Smuzhiyun
863*4882a593Smuzhiyun status = rsi_setupcard(adapter);
864*4882a593Smuzhiyun if (status) {
865*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed to setup card\n", __func__);
866*4882a593Smuzhiyun goto fail;
867*4882a593Smuzhiyun }
868*4882a593Smuzhiyun
869*4882a593Smuzhiyun rsi_dbg(INIT_ZONE, "%s: Setup card successfully\n", __func__);
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun status = rsi_init_sdio_slave_regs(adapter);
872*4882a593Smuzhiyun if (status) {
873*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed to init slave regs\n", __func__);
874*4882a593Smuzhiyun goto fail;
875*4882a593Smuzhiyun }
876*4882a593Smuzhiyun sdio_release_host(pfunction);
877*4882a593Smuzhiyun
878*4882a593Smuzhiyun adapter->determine_event_timeout = rsi_sdio_determine_event_timeout;
879*4882a593Smuzhiyun adapter->check_hw_queue_status = rsi_sdio_check_buffer_status;
880*4882a593Smuzhiyun
881*4882a593Smuzhiyun #ifdef CONFIG_RSI_DEBUGFS
882*4882a593Smuzhiyun adapter->num_debugfs_entries = MAX_DEBUGFS_ENTRIES;
883*4882a593Smuzhiyun #endif
884*4882a593Smuzhiyun return 0;
885*4882a593Smuzhiyun fail:
886*4882a593Smuzhiyun sdio_disable_func(pfunction);
887*4882a593Smuzhiyun sdio_release_host(pfunction);
888*4882a593Smuzhiyun return status;
889*4882a593Smuzhiyun }
890*4882a593Smuzhiyun
rsi_sdio_reinit_device(struct rsi_hw * adapter)891*4882a593Smuzhiyun static int rsi_sdio_reinit_device(struct rsi_hw *adapter)
892*4882a593Smuzhiyun {
893*4882a593Smuzhiyun struct rsi_91x_sdiodev *sdev = adapter->rsi_dev;
894*4882a593Smuzhiyun struct sdio_func *pfunction = sdev->pfunction;
895*4882a593Smuzhiyun int ii;
896*4882a593Smuzhiyun
897*4882a593Smuzhiyun for (ii = 0; ii < NUM_SOFT_QUEUES; ii++)
898*4882a593Smuzhiyun skb_queue_purge(&adapter->priv->tx_queue[ii]);
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun /* Initialize device again */
901*4882a593Smuzhiyun sdio_claim_host(pfunction);
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun sdio_release_irq(pfunction);
904*4882a593Smuzhiyun rsi_reset_card(pfunction);
905*4882a593Smuzhiyun
906*4882a593Smuzhiyun sdio_enable_func(pfunction);
907*4882a593Smuzhiyun rsi_setupcard(adapter);
908*4882a593Smuzhiyun rsi_init_sdio_slave_regs(adapter);
909*4882a593Smuzhiyun sdio_claim_irq(pfunction, rsi_handle_interrupt);
910*4882a593Smuzhiyun rsi_hal_device_init(adapter);
911*4882a593Smuzhiyun
912*4882a593Smuzhiyun sdio_release_host(pfunction);
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun return 0;
915*4882a593Smuzhiyun }
916*4882a593Smuzhiyun
rsi_sdio_ta_reset(struct rsi_hw * adapter)917*4882a593Smuzhiyun static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
918*4882a593Smuzhiyun {
919*4882a593Smuzhiyun int status;
920*4882a593Smuzhiyun u32 addr;
921*4882a593Smuzhiyun u8 *data;
922*4882a593Smuzhiyun
923*4882a593Smuzhiyun data = kzalloc(RSI_9116_REG_SIZE, GFP_KERNEL);
924*4882a593Smuzhiyun if (!data)
925*4882a593Smuzhiyun return -ENOMEM;
926*4882a593Smuzhiyun
927*4882a593Smuzhiyun status = rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR);
928*4882a593Smuzhiyun if (status < 0) {
929*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
930*4882a593Smuzhiyun "Unable to set ms word to common reg\n");
931*4882a593Smuzhiyun goto err;
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun rsi_dbg(INIT_ZONE, "%s: Bring TA out of reset\n", __func__);
935*4882a593Smuzhiyun put_unaligned_le32(TA_HOLD_THREAD_VALUE, data);
936*4882a593Smuzhiyun addr = TA_HOLD_THREAD_REG | RSI_SD_REQUEST_MASTER;
937*4882a593Smuzhiyun status = rsi_sdio_write_register_multiple(adapter, addr,
938*4882a593Smuzhiyun (u8 *)data,
939*4882a593Smuzhiyun RSI_9116_REG_SIZE);
940*4882a593Smuzhiyun if (status < 0) {
941*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Unable to hold TA threads\n");
942*4882a593Smuzhiyun goto err;
943*4882a593Smuzhiyun }
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun put_unaligned_le32(TA_SOFT_RST_CLR, data);
946*4882a593Smuzhiyun addr = TA_SOFT_RESET_REG | RSI_SD_REQUEST_MASTER;
947*4882a593Smuzhiyun status = rsi_sdio_write_register_multiple(adapter, addr,
948*4882a593Smuzhiyun (u8 *)data,
949*4882a593Smuzhiyun RSI_9116_REG_SIZE);
950*4882a593Smuzhiyun if (status < 0) {
951*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Unable to get TA out of reset\n");
952*4882a593Smuzhiyun goto err;
953*4882a593Smuzhiyun }
954*4882a593Smuzhiyun
955*4882a593Smuzhiyun put_unaligned_le32(TA_PC_ZERO, data);
956*4882a593Smuzhiyun addr = TA_TH0_PC_REG | RSI_SD_REQUEST_MASTER;
957*4882a593Smuzhiyun status = rsi_sdio_write_register_multiple(adapter, addr,
958*4882a593Smuzhiyun (u8 *)data,
959*4882a593Smuzhiyun RSI_9116_REG_SIZE);
960*4882a593Smuzhiyun if (status < 0) {
961*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Unable to Reset TA PC value\n");
962*4882a593Smuzhiyun status = -EINVAL;
963*4882a593Smuzhiyun goto err;
964*4882a593Smuzhiyun }
965*4882a593Smuzhiyun
966*4882a593Smuzhiyun put_unaligned_le32(TA_RELEASE_THREAD_VALUE, data);
967*4882a593Smuzhiyun addr = TA_RELEASE_THREAD_REG | RSI_SD_REQUEST_MASTER;
968*4882a593Smuzhiyun status = rsi_sdio_write_register_multiple(adapter, addr,
969*4882a593Smuzhiyun (u8 *)data,
970*4882a593Smuzhiyun RSI_9116_REG_SIZE);
971*4882a593Smuzhiyun if (status < 0) {
972*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Unable to release TA threads\n");
973*4882a593Smuzhiyun goto err;
974*4882a593Smuzhiyun }
975*4882a593Smuzhiyun
976*4882a593Smuzhiyun status = rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR);
977*4882a593Smuzhiyun if (status < 0) {
978*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Unable to set ms word to common reg\n");
979*4882a593Smuzhiyun goto err;
980*4882a593Smuzhiyun }
981*4882a593Smuzhiyun rsi_dbg(INIT_ZONE, "***** TA Reset done *****\n");
982*4882a593Smuzhiyun
983*4882a593Smuzhiyun err:
984*4882a593Smuzhiyun kfree(data);
985*4882a593Smuzhiyun return status;
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun
988*4882a593Smuzhiyun static struct rsi_host_intf_ops sdio_host_intf_ops = {
989*4882a593Smuzhiyun .write_pkt = rsi_sdio_host_intf_write_pkt,
990*4882a593Smuzhiyun .read_pkt = rsi_sdio_host_intf_read_pkt,
991*4882a593Smuzhiyun .master_access_msword = rsi_sdio_master_access_msword,
992*4882a593Smuzhiyun .read_reg_multiple = rsi_sdio_read_register_multiple,
993*4882a593Smuzhiyun .write_reg_multiple = rsi_sdio_write_register_multiple,
994*4882a593Smuzhiyun .master_reg_read = rsi_sdio_master_reg_read,
995*4882a593Smuzhiyun .master_reg_write = rsi_sdio_master_reg_write,
996*4882a593Smuzhiyun .load_data_master_write = rsi_sdio_load_data_master_write,
997*4882a593Smuzhiyun .reinit_device = rsi_sdio_reinit_device,
998*4882a593Smuzhiyun .ta_reset = rsi_sdio_ta_reset,
999*4882a593Smuzhiyun };
1000*4882a593Smuzhiyun
1001*4882a593Smuzhiyun /**
1002*4882a593Smuzhiyun * rsi_probe() - This function is called by kernel when the driver provided
1003*4882a593Smuzhiyun * Vendor and device IDs are matched. All the initialization
1004*4882a593Smuzhiyun * work is done here.
1005*4882a593Smuzhiyun * @pfunction: Pointer to the sdio_func structure.
1006*4882a593Smuzhiyun * @id: Pointer to sdio_device_id structure.
1007*4882a593Smuzhiyun *
1008*4882a593Smuzhiyun * Return: 0 on success, 1 on failure.
1009*4882a593Smuzhiyun */
rsi_probe(struct sdio_func * pfunction,const struct sdio_device_id * id)1010*4882a593Smuzhiyun static int rsi_probe(struct sdio_func *pfunction,
1011*4882a593Smuzhiyun const struct sdio_device_id *id)
1012*4882a593Smuzhiyun {
1013*4882a593Smuzhiyun struct rsi_hw *adapter;
1014*4882a593Smuzhiyun struct rsi_91x_sdiodev *sdev;
1015*4882a593Smuzhiyun int status = -EINVAL;
1016*4882a593Smuzhiyun
1017*4882a593Smuzhiyun rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
1018*4882a593Smuzhiyun
1019*4882a593Smuzhiyun adapter = rsi_91x_init(dev_oper_mode);
1020*4882a593Smuzhiyun if (!adapter) {
1021*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
1022*4882a593Smuzhiyun __func__);
1023*4882a593Smuzhiyun return -EINVAL;
1024*4882a593Smuzhiyun }
1025*4882a593Smuzhiyun adapter->rsi_host_intf = RSI_HOST_INTF_SDIO;
1026*4882a593Smuzhiyun adapter->host_intf_ops = &sdio_host_intf_ops;
1027*4882a593Smuzhiyun
1028*4882a593Smuzhiyun if (rsi_init_sdio_interface(adapter, pfunction)) {
1029*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed to init sdio interface\n",
1030*4882a593Smuzhiyun __func__);
1031*4882a593Smuzhiyun status = -EIO;
1032*4882a593Smuzhiyun goto fail_free_adapter;
1033*4882a593Smuzhiyun }
1034*4882a593Smuzhiyun
1035*4882a593Smuzhiyun if (pfunction->device == SDIO_DEVICE_ID_RSI_9113) {
1036*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: 9113 module detected\n", __func__);
1037*4882a593Smuzhiyun adapter->device_model = RSI_DEV_9113;
1038*4882a593Smuzhiyun } else if (pfunction->device == SDIO_DEVICE_ID_RSI_9116) {
1039*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: 9116 module detected\n", __func__);
1040*4882a593Smuzhiyun adapter->device_model = RSI_DEV_9116;
1041*4882a593Smuzhiyun } else {
1042*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1043*4882a593Smuzhiyun "%s: Unsupported RSI device id 0x%x\n", __func__,
1044*4882a593Smuzhiyun pfunction->device);
1045*4882a593Smuzhiyun goto fail_free_adapter;
1046*4882a593Smuzhiyun }
1047*4882a593Smuzhiyun
1048*4882a593Smuzhiyun sdev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;
1049*4882a593Smuzhiyun rsi_init_event(&sdev->rx_thread.event);
1050*4882a593Smuzhiyun status = rsi_create_kthread(adapter->priv, &sdev->rx_thread,
1051*4882a593Smuzhiyun rsi_sdio_rx_thread, "SDIO-RX-Thread");
1052*4882a593Smuzhiyun if (status) {
1053*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
1054*4882a593Smuzhiyun goto fail_kill_thread;
1055*4882a593Smuzhiyun }
1056*4882a593Smuzhiyun
1057*4882a593Smuzhiyun sdio_claim_host(pfunction);
1058*4882a593Smuzhiyun if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) {
1059*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__);
1060*4882a593Smuzhiyun sdio_release_host(pfunction);
1061*4882a593Smuzhiyun status = -EIO;
1062*4882a593Smuzhiyun goto fail_claim_irq;
1063*4882a593Smuzhiyun }
1064*4882a593Smuzhiyun sdio_release_host(pfunction);
1065*4882a593Smuzhiyun rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__);
1066*4882a593Smuzhiyun
1067*4882a593Smuzhiyun if (rsi_hal_device_init(adapter)) {
1068*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__);
1069*4882a593Smuzhiyun status = -EINVAL;
1070*4882a593Smuzhiyun goto fail_dev_init;
1071*4882a593Smuzhiyun }
1072*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "===> RSI Device Init Done <===\n");
1073*4882a593Smuzhiyun
1074*4882a593Smuzhiyun if (rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR)) {
1075*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", __func__);
1076*4882a593Smuzhiyun status = -EIO;
1077*4882a593Smuzhiyun goto fail_dev_init;
1078*4882a593Smuzhiyun }
1079*4882a593Smuzhiyun
1080*4882a593Smuzhiyun adapter->priv->hibernate_resume = false;
1081*4882a593Smuzhiyun adapter->priv->reinit_hw = false;
1082*4882a593Smuzhiyun return 0;
1083*4882a593Smuzhiyun
1084*4882a593Smuzhiyun fail_dev_init:
1085*4882a593Smuzhiyun sdio_claim_host(pfunction);
1086*4882a593Smuzhiyun sdio_release_irq(pfunction);
1087*4882a593Smuzhiyun sdio_release_host(pfunction);
1088*4882a593Smuzhiyun fail_claim_irq:
1089*4882a593Smuzhiyun rsi_kill_thread(&sdev->rx_thread);
1090*4882a593Smuzhiyun fail_kill_thread:
1091*4882a593Smuzhiyun sdio_claim_host(pfunction);
1092*4882a593Smuzhiyun sdio_disable_func(pfunction);
1093*4882a593Smuzhiyun sdio_release_host(pfunction);
1094*4882a593Smuzhiyun fail_free_adapter:
1095*4882a593Smuzhiyun rsi_91x_deinit(adapter);
1096*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
1097*4882a593Smuzhiyun return status;
1098*4882a593Smuzhiyun }
1099*4882a593Smuzhiyun
ulp_read_write(struct rsi_hw * adapter,u16 addr,u32 data,u16 len_in_bits)1100*4882a593Smuzhiyun static void ulp_read_write(struct rsi_hw *adapter, u16 addr, u32 data,
1101*4882a593Smuzhiyun u16 len_in_bits)
1102*4882a593Smuzhiyun {
1103*4882a593Smuzhiyun rsi_sdio_master_reg_write(adapter, RSI_GSPI_DATA_REG1,
1104*4882a593Smuzhiyun ((addr << 6) | ((data >> 16) & 0xffff)), 2);
1105*4882a593Smuzhiyun rsi_sdio_master_reg_write(adapter, RSI_GSPI_DATA_REG0,
1106*4882a593Smuzhiyun (data & 0xffff), 2);
1107*4882a593Smuzhiyun rsi_sdio_master_reg_write(adapter, RSI_GSPI_CTRL_REG0,
1108*4882a593Smuzhiyun RSI_GSPI_CTRL_REG0_VALUE, 2);
1109*4882a593Smuzhiyun rsi_sdio_master_reg_write(adapter, RSI_GSPI_CTRL_REG1,
1110*4882a593Smuzhiyun ((len_in_bits - 1) | RSI_GSPI_TRIG), 2);
1111*4882a593Smuzhiyun msleep(20);
1112*4882a593Smuzhiyun }
1113*4882a593Smuzhiyun
1114*4882a593Smuzhiyun /*This function resets and re-initializes the chip.*/
rsi_reset_chip(struct rsi_hw * adapter)1115*4882a593Smuzhiyun static void rsi_reset_chip(struct rsi_hw *adapter)
1116*4882a593Smuzhiyun {
1117*4882a593Smuzhiyun u8 *data;
1118*4882a593Smuzhiyun u8 sdio_interrupt_status = 0;
1119*4882a593Smuzhiyun u8 request = 1;
1120*4882a593Smuzhiyun int ret;
1121*4882a593Smuzhiyun
1122*4882a593Smuzhiyun data = kzalloc(sizeof(u32), GFP_KERNEL);
1123*4882a593Smuzhiyun if (!data)
1124*4882a593Smuzhiyun return;
1125*4882a593Smuzhiyun
1126*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "Writing disable to wakeup register\n");
1127*4882a593Smuzhiyun ret = rsi_sdio_write_register(adapter, 0, SDIO_WAKEUP_REG, &request);
1128*4882a593Smuzhiyun if (ret < 0) {
1129*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1130*4882a593Smuzhiyun "%s: Failed to write SDIO wakeup register\n", __func__);
1131*4882a593Smuzhiyun goto err;
1132*4882a593Smuzhiyun }
1133*4882a593Smuzhiyun msleep(20);
1134*4882a593Smuzhiyun ret = rsi_sdio_read_register(adapter, RSI_FN1_INT_REGISTER,
1135*4882a593Smuzhiyun &sdio_interrupt_status);
1136*4882a593Smuzhiyun if (ret < 0) {
1137*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "%s: Failed to Read Intr Status Register\n",
1138*4882a593Smuzhiyun __func__);
1139*4882a593Smuzhiyun goto err;
1140*4882a593Smuzhiyun }
1141*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "%s: Intr Status Register value = %d\n",
1142*4882a593Smuzhiyun __func__, sdio_interrupt_status);
1143*4882a593Smuzhiyun
1144*4882a593Smuzhiyun /* Put Thread-Arch processor on hold */
1145*4882a593Smuzhiyun if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) {
1146*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1147*4882a593Smuzhiyun "%s: Unable to set ms word to common reg\n",
1148*4882a593Smuzhiyun __func__);
1149*4882a593Smuzhiyun goto err;
1150*4882a593Smuzhiyun }
1151*4882a593Smuzhiyun
1152*4882a593Smuzhiyun put_unaligned_le32(TA_HOLD_THREAD_VALUE, data);
1153*4882a593Smuzhiyun if (rsi_sdio_write_register_multiple(adapter, TA_HOLD_THREAD_REG |
1154*4882a593Smuzhiyun RSI_SD_REQUEST_MASTER,
1155*4882a593Smuzhiyun data, 4)) {
1156*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1157*4882a593Smuzhiyun "%s: Unable to hold Thread-Arch processor threads\n",
1158*4882a593Smuzhiyun __func__);
1159*4882a593Smuzhiyun goto err;
1160*4882a593Smuzhiyun }
1161*4882a593Smuzhiyun
1162*4882a593Smuzhiyun /* This msleep will ensure Thread-Arch processor to go to hold
1163*4882a593Smuzhiyun * and any pending dma transfers to rf spi in device to finish.
1164*4882a593Smuzhiyun */
1165*4882a593Smuzhiyun msleep(100);
1166*4882a593Smuzhiyun if (adapter->device_model != RSI_DEV_9116) {
1167*4882a593Smuzhiyun ulp_read_write(adapter, RSI_ULP_RESET_REG, RSI_ULP_WRITE_0, 32);
1168*4882a593Smuzhiyun ulp_read_write(adapter,
1169*4882a593Smuzhiyun RSI_WATCH_DOG_TIMER_1, RSI_ULP_WRITE_2, 32);
1170*4882a593Smuzhiyun ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_2, RSI_ULP_WRITE_0,
1171*4882a593Smuzhiyun 32);
1172*4882a593Smuzhiyun ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_1,
1173*4882a593Smuzhiyun RSI_ULP_WRITE_50, 32);
1174*4882a593Smuzhiyun ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_2,
1175*4882a593Smuzhiyun RSI_ULP_WRITE_0, 32);
1176*4882a593Smuzhiyun ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_ENABLE,
1177*4882a593Smuzhiyun RSI_ULP_TIMER_ENABLE, 32);
1178*4882a593Smuzhiyun } else {
1179*4882a593Smuzhiyun if ((rsi_sdio_master_reg_write(adapter,
1180*4882a593Smuzhiyun NWP_WWD_INTERRUPT_TIMER,
1181*4882a593Smuzhiyun NWP_WWD_INT_TIMER_CLKS,
1182*4882a593Smuzhiyun RSI_9116_REG_SIZE)) < 0) {
1183*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Failed to write to intr timer\n");
1184*4882a593Smuzhiyun }
1185*4882a593Smuzhiyun if ((rsi_sdio_master_reg_write(adapter,
1186*4882a593Smuzhiyun NWP_WWD_SYSTEM_RESET_TIMER,
1187*4882a593Smuzhiyun NWP_WWD_SYS_RESET_TIMER_CLKS,
1188*4882a593Smuzhiyun RSI_9116_REG_SIZE)) < 0) {
1189*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1190*4882a593Smuzhiyun "Failed to write to system reset timer\n");
1191*4882a593Smuzhiyun }
1192*4882a593Smuzhiyun if ((rsi_sdio_master_reg_write(adapter,
1193*4882a593Smuzhiyun NWP_WWD_MODE_AND_RSTART,
1194*4882a593Smuzhiyun NWP_WWD_TIMER_DISABLE,
1195*4882a593Smuzhiyun RSI_9116_REG_SIZE)) < 0) {
1196*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1197*4882a593Smuzhiyun "Failed to write to mode and restart\n");
1198*4882a593Smuzhiyun }
1199*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "***** Watch Dog Reset Successful *****\n");
1200*4882a593Smuzhiyun }
1201*4882a593Smuzhiyun /* This msleep will be sufficient for the ulp
1202*4882a593Smuzhiyun * read write operations to complete for chip reset.
1203*4882a593Smuzhiyun */
1204*4882a593Smuzhiyun msleep(500);
1205*4882a593Smuzhiyun err:
1206*4882a593Smuzhiyun kfree(data);
1207*4882a593Smuzhiyun return;
1208*4882a593Smuzhiyun }
1209*4882a593Smuzhiyun
1210*4882a593Smuzhiyun /**
1211*4882a593Smuzhiyun * rsi_disconnect() - This function performs the reverse of the probe function.
1212*4882a593Smuzhiyun * @pfunction: Pointer to the sdio_func structure.
1213*4882a593Smuzhiyun *
1214*4882a593Smuzhiyun * Return: void.
1215*4882a593Smuzhiyun */
rsi_disconnect(struct sdio_func * pfunction)1216*4882a593Smuzhiyun static void rsi_disconnect(struct sdio_func *pfunction)
1217*4882a593Smuzhiyun {
1218*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
1219*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev;
1220*4882a593Smuzhiyun
1221*4882a593Smuzhiyun if (!adapter)
1222*4882a593Smuzhiyun return;
1223*4882a593Smuzhiyun
1224*4882a593Smuzhiyun dev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;
1225*4882a593Smuzhiyun
1226*4882a593Smuzhiyun rsi_kill_thread(&dev->rx_thread);
1227*4882a593Smuzhiyun sdio_claim_host(pfunction);
1228*4882a593Smuzhiyun sdio_release_irq(pfunction);
1229*4882a593Smuzhiyun sdio_release_host(pfunction);
1230*4882a593Smuzhiyun mdelay(10);
1231*4882a593Smuzhiyun
1232*4882a593Smuzhiyun rsi_mac80211_detach(adapter);
1233*4882a593Smuzhiyun mdelay(10);
1234*4882a593Smuzhiyun
1235*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_RSI_COEX) && adapter->priv->coex_mode > 1 &&
1236*4882a593Smuzhiyun adapter->priv->bt_adapter) {
1237*4882a593Smuzhiyun rsi_bt_ops.detach(adapter->priv->bt_adapter);
1238*4882a593Smuzhiyun adapter->priv->bt_adapter = NULL;
1239*4882a593Smuzhiyun }
1240*4882a593Smuzhiyun
1241*4882a593Smuzhiyun /* Reset Chip */
1242*4882a593Smuzhiyun rsi_reset_chip(adapter);
1243*4882a593Smuzhiyun
1244*4882a593Smuzhiyun /* Resetting to take care of the case, where-in driver is re-loaded */
1245*4882a593Smuzhiyun sdio_claim_host(pfunction);
1246*4882a593Smuzhiyun rsi_reset_card(pfunction);
1247*4882a593Smuzhiyun sdio_disable_func(pfunction);
1248*4882a593Smuzhiyun sdio_release_host(pfunction);
1249*4882a593Smuzhiyun dev->write_fail = 2;
1250*4882a593Smuzhiyun rsi_91x_deinit(adapter);
1251*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "##### RSI SDIO device disconnected #####\n");
1252*4882a593Smuzhiyun
1253*4882a593Smuzhiyun }
1254*4882a593Smuzhiyun
1255*4882a593Smuzhiyun #ifdef CONFIG_PM
rsi_set_sdio_pm_caps(struct rsi_hw * adapter)1256*4882a593Smuzhiyun static int rsi_set_sdio_pm_caps(struct rsi_hw *adapter)
1257*4882a593Smuzhiyun {
1258*4882a593Smuzhiyun struct rsi_91x_sdiodev *dev =
1259*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
1260*4882a593Smuzhiyun struct sdio_func *func = dev->pfunction;
1261*4882a593Smuzhiyun int ret;
1262*4882a593Smuzhiyun
1263*4882a593Smuzhiyun ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
1264*4882a593Smuzhiyun if (ret)
1265*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Set sdio keep pwr flag failed: %d\n", ret);
1266*4882a593Smuzhiyun
1267*4882a593Smuzhiyun return ret;
1268*4882a593Smuzhiyun }
1269*4882a593Smuzhiyun
rsi_sdio_disable_interrupts(struct sdio_func * pfunc)1270*4882a593Smuzhiyun static int rsi_sdio_disable_interrupts(struct sdio_func *pfunc)
1271*4882a593Smuzhiyun {
1272*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(pfunc);
1273*4882a593Smuzhiyun u8 isr_status = 0, data = 0;
1274*4882a593Smuzhiyun int ret;
1275*4882a593Smuzhiyun unsigned long t1;
1276*4882a593Smuzhiyun
1277*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "Waiting for interrupts to be cleared..");
1278*4882a593Smuzhiyun t1 = jiffies;
1279*4882a593Smuzhiyun do {
1280*4882a593Smuzhiyun rsi_sdio_read_register(adapter, RSI_FN1_INT_REGISTER,
1281*4882a593Smuzhiyun &isr_status);
1282*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, ".");
1283*4882a593Smuzhiyun } while ((isr_status) && (jiffies_to_msecs(jiffies - t1) < 20));
1284*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "Interrupts cleared\n");
1285*4882a593Smuzhiyun
1286*4882a593Smuzhiyun sdio_claim_host(pfunc);
1287*4882a593Smuzhiyun ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data);
1288*4882a593Smuzhiyun if (ret < 0) {
1289*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1290*4882a593Smuzhiyun "%s: Failed to read int enable register\n",
1291*4882a593Smuzhiyun __func__);
1292*4882a593Smuzhiyun goto done;
1293*4882a593Smuzhiyun }
1294*4882a593Smuzhiyun
1295*4882a593Smuzhiyun data &= RSI_INT_ENABLE_MASK;
1296*4882a593Smuzhiyun ret = rsi_cmd52writebyte(pfunc->card, RSI_INT_ENABLE_REGISTER, data);
1297*4882a593Smuzhiyun if (ret < 0) {
1298*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1299*4882a593Smuzhiyun "%s: Failed to write to int enable register\n",
1300*4882a593Smuzhiyun __func__);
1301*4882a593Smuzhiyun goto done;
1302*4882a593Smuzhiyun }
1303*4882a593Smuzhiyun ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data);
1304*4882a593Smuzhiyun if (ret < 0) {
1305*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1306*4882a593Smuzhiyun "%s: Failed to read int enable register\n",
1307*4882a593Smuzhiyun __func__);
1308*4882a593Smuzhiyun goto done;
1309*4882a593Smuzhiyun }
1310*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "int enable reg content = %x\n", data);
1311*4882a593Smuzhiyun
1312*4882a593Smuzhiyun done:
1313*4882a593Smuzhiyun sdio_release_host(pfunc);
1314*4882a593Smuzhiyun return ret;
1315*4882a593Smuzhiyun }
1316*4882a593Smuzhiyun
rsi_sdio_enable_interrupts(struct sdio_func * pfunc)1317*4882a593Smuzhiyun static int rsi_sdio_enable_interrupts(struct sdio_func *pfunc)
1318*4882a593Smuzhiyun {
1319*4882a593Smuzhiyun u8 data;
1320*4882a593Smuzhiyun int ret;
1321*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(pfunc);
1322*4882a593Smuzhiyun struct rsi_common *common = adapter->priv;
1323*4882a593Smuzhiyun
1324*4882a593Smuzhiyun sdio_claim_host(pfunc);
1325*4882a593Smuzhiyun ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data);
1326*4882a593Smuzhiyun if (ret < 0) {
1327*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1328*4882a593Smuzhiyun "%s: Failed to read int enable register\n", __func__);
1329*4882a593Smuzhiyun goto done;
1330*4882a593Smuzhiyun }
1331*4882a593Smuzhiyun
1332*4882a593Smuzhiyun data |= ~RSI_INT_ENABLE_MASK & 0xff;
1333*4882a593Smuzhiyun
1334*4882a593Smuzhiyun ret = rsi_cmd52writebyte(pfunc->card, RSI_INT_ENABLE_REGISTER, data);
1335*4882a593Smuzhiyun if (ret < 0) {
1336*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1337*4882a593Smuzhiyun "%s: Failed to write to int enable register\n",
1338*4882a593Smuzhiyun __func__);
1339*4882a593Smuzhiyun goto done;
1340*4882a593Smuzhiyun }
1341*4882a593Smuzhiyun
1342*4882a593Smuzhiyun if ((common->wow_flags & RSI_WOW_ENABLED) &&
1343*4882a593Smuzhiyun (common->wow_flags & RSI_WOW_NO_CONNECTION))
1344*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1345*4882a593Smuzhiyun "##### Device can not wake up through WLAN\n");
1346*4882a593Smuzhiyun
1347*4882a593Smuzhiyun ret = rsi_cmd52readbyte(pfunc->card, RSI_INT_ENABLE_REGISTER, &data);
1348*4882a593Smuzhiyun if (ret < 0) {
1349*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1350*4882a593Smuzhiyun "%s: Failed to read int enable register\n", __func__);
1351*4882a593Smuzhiyun goto done;
1352*4882a593Smuzhiyun }
1353*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "int enable reg content = %x\n", data);
1354*4882a593Smuzhiyun
1355*4882a593Smuzhiyun done:
1356*4882a593Smuzhiyun sdio_release_host(pfunc);
1357*4882a593Smuzhiyun return ret;
1358*4882a593Smuzhiyun }
1359*4882a593Smuzhiyun
rsi_suspend(struct device * dev)1360*4882a593Smuzhiyun static int rsi_suspend(struct device *dev)
1361*4882a593Smuzhiyun {
1362*4882a593Smuzhiyun int ret;
1363*4882a593Smuzhiyun struct sdio_func *pfunction = dev_to_sdio_func(dev);
1364*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
1365*4882a593Smuzhiyun struct rsi_common *common;
1366*4882a593Smuzhiyun
1367*4882a593Smuzhiyun if (!adapter) {
1368*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Device is not ready\n");
1369*4882a593Smuzhiyun return -ENODEV;
1370*4882a593Smuzhiyun }
1371*4882a593Smuzhiyun common = adapter->priv;
1372*4882a593Smuzhiyun rsi_sdio_disable_interrupts(pfunction);
1373*4882a593Smuzhiyun
1374*4882a593Smuzhiyun ret = rsi_set_sdio_pm_caps(adapter);
1375*4882a593Smuzhiyun if (ret)
1376*4882a593Smuzhiyun rsi_dbg(INFO_ZONE,
1377*4882a593Smuzhiyun "Setting power management caps failed\n");
1378*4882a593Smuzhiyun common->fsm_state = FSM_CARD_NOT_READY;
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun return 0;
1381*4882a593Smuzhiyun }
1382*4882a593Smuzhiyun
rsi_resume(struct device * dev)1383*4882a593Smuzhiyun static int rsi_resume(struct device *dev)
1384*4882a593Smuzhiyun {
1385*4882a593Smuzhiyun struct sdio_func *pfunction = dev_to_sdio_func(dev);
1386*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
1387*4882a593Smuzhiyun struct rsi_common *common = adapter->priv;
1388*4882a593Smuzhiyun
1389*4882a593Smuzhiyun common->fsm_state = FSM_MAC_INIT_DONE;
1390*4882a593Smuzhiyun rsi_sdio_enable_interrupts(pfunction);
1391*4882a593Smuzhiyun
1392*4882a593Smuzhiyun return 0;
1393*4882a593Smuzhiyun }
1394*4882a593Smuzhiyun
rsi_freeze(struct device * dev)1395*4882a593Smuzhiyun static int rsi_freeze(struct device *dev)
1396*4882a593Smuzhiyun {
1397*4882a593Smuzhiyun int ret;
1398*4882a593Smuzhiyun struct sdio_func *pfunction = dev_to_sdio_func(dev);
1399*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
1400*4882a593Smuzhiyun struct rsi_common *common;
1401*4882a593Smuzhiyun struct rsi_91x_sdiodev *sdev;
1402*4882a593Smuzhiyun
1403*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "SDIO Bus freeze ===>\n");
1404*4882a593Smuzhiyun
1405*4882a593Smuzhiyun if (!adapter) {
1406*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Device is not ready\n");
1407*4882a593Smuzhiyun return -ENODEV;
1408*4882a593Smuzhiyun }
1409*4882a593Smuzhiyun common = adapter->priv;
1410*4882a593Smuzhiyun sdev = (struct rsi_91x_sdiodev *)adapter->rsi_dev;
1411*4882a593Smuzhiyun
1412*4882a593Smuzhiyun if ((common->wow_flags & RSI_WOW_ENABLED) &&
1413*4882a593Smuzhiyun (common->wow_flags & RSI_WOW_NO_CONNECTION))
1414*4882a593Smuzhiyun rsi_dbg(ERR_ZONE,
1415*4882a593Smuzhiyun "##### Device can not wake up through WLAN\n");
1416*4882a593Smuzhiyun
1417*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_RSI_COEX) && common->coex_mode > 1 &&
1418*4882a593Smuzhiyun common->bt_adapter) {
1419*4882a593Smuzhiyun rsi_bt_ops.detach(common->bt_adapter);
1420*4882a593Smuzhiyun common->bt_adapter = NULL;
1421*4882a593Smuzhiyun }
1422*4882a593Smuzhiyun
1423*4882a593Smuzhiyun ret = rsi_sdio_disable_interrupts(pfunction);
1424*4882a593Smuzhiyun
1425*4882a593Smuzhiyun if (sdev->write_fail)
1426*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");
1427*4882a593Smuzhiyun
1428*4882a593Smuzhiyun ret = rsi_set_sdio_pm_caps(adapter);
1429*4882a593Smuzhiyun if (ret)
1430*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "Setting power management caps failed\n");
1431*4882a593Smuzhiyun
1432*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "***** RSI module freezed *****\n");
1433*4882a593Smuzhiyun
1434*4882a593Smuzhiyun return 0;
1435*4882a593Smuzhiyun }
1436*4882a593Smuzhiyun
rsi_thaw(struct device * dev)1437*4882a593Smuzhiyun static int rsi_thaw(struct device *dev)
1438*4882a593Smuzhiyun {
1439*4882a593Smuzhiyun struct sdio_func *pfunction = dev_to_sdio_func(dev);
1440*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
1441*4882a593Smuzhiyun struct rsi_common *common = adapter->priv;
1442*4882a593Smuzhiyun
1443*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "SDIO Bus thaw =====>\n");
1444*4882a593Smuzhiyun
1445*4882a593Smuzhiyun common->hibernate_resume = true;
1446*4882a593Smuzhiyun common->fsm_state = FSM_CARD_NOT_READY;
1447*4882a593Smuzhiyun common->iface_down = true;
1448*4882a593Smuzhiyun
1449*4882a593Smuzhiyun rsi_sdio_enable_interrupts(pfunction);
1450*4882a593Smuzhiyun
1451*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "***** RSI module thaw done *****\n");
1452*4882a593Smuzhiyun
1453*4882a593Smuzhiyun return 0;
1454*4882a593Smuzhiyun }
1455*4882a593Smuzhiyun
rsi_shutdown(struct device * dev)1456*4882a593Smuzhiyun static void rsi_shutdown(struct device *dev)
1457*4882a593Smuzhiyun {
1458*4882a593Smuzhiyun struct sdio_func *pfunction = dev_to_sdio_func(dev);
1459*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
1460*4882a593Smuzhiyun struct rsi_91x_sdiodev *sdev =
1461*4882a593Smuzhiyun (struct rsi_91x_sdiodev *)adapter->rsi_dev;
1462*4882a593Smuzhiyun struct ieee80211_hw *hw = adapter->hw;
1463*4882a593Smuzhiyun
1464*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "SDIO Bus shutdown =====>\n");
1465*4882a593Smuzhiyun
1466*4882a593Smuzhiyun if (hw) {
1467*4882a593Smuzhiyun struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config;
1468*4882a593Smuzhiyun
1469*4882a593Smuzhiyun if (rsi_config_wowlan(adapter, wowlan))
1470*4882a593Smuzhiyun rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n");
1471*4882a593Smuzhiyun }
1472*4882a593Smuzhiyun
1473*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_RSI_COEX) && adapter->priv->coex_mode > 1 &&
1474*4882a593Smuzhiyun adapter->priv->bt_adapter) {
1475*4882a593Smuzhiyun rsi_bt_ops.detach(adapter->priv->bt_adapter);
1476*4882a593Smuzhiyun adapter->priv->bt_adapter = NULL;
1477*4882a593Smuzhiyun }
1478*4882a593Smuzhiyun
1479*4882a593Smuzhiyun rsi_sdio_disable_interrupts(sdev->pfunction);
1480*4882a593Smuzhiyun
1481*4882a593Smuzhiyun if (sdev->write_fail)
1482*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n");
1483*4882a593Smuzhiyun
1484*4882a593Smuzhiyun if (rsi_set_sdio_pm_caps(adapter))
1485*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "Setting power management caps failed\n");
1486*4882a593Smuzhiyun
1487*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n");
1488*4882a593Smuzhiyun }
1489*4882a593Smuzhiyun
rsi_restore(struct device * dev)1490*4882a593Smuzhiyun static int rsi_restore(struct device *dev)
1491*4882a593Smuzhiyun {
1492*4882a593Smuzhiyun struct sdio_func *pfunction = dev_to_sdio_func(dev);
1493*4882a593Smuzhiyun struct rsi_hw *adapter = sdio_get_drvdata(pfunction);
1494*4882a593Smuzhiyun struct rsi_common *common = adapter->priv;
1495*4882a593Smuzhiyun
1496*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "SDIO Bus restore ======>\n");
1497*4882a593Smuzhiyun common->hibernate_resume = true;
1498*4882a593Smuzhiyun common->fsm_state = FSM_FW_NOT_LOADED;
1499*4882a593Smuzhiyun common->iface_down = true;
1500*4882a593Smuzhiyun
1501*4882a593Smuzhiyun adapter->sc_nvifs = 0;
1502*4882a593Smuzhiyun adapter->ps_state = PS_NONE;
1503*4882a593Smuzhiyun
1504*4882a593Smuzhiyun common->wow_flags = 0;
1505*4882a593Smuzhiyun common->iface_down = false;
1506*4882a593Smuzhiyun
1507*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "RSI module restored\n");
1508*4882a593Smuzhiyun
1509*4882a593Smuzhiyun return 0;
1510*4882a593Smuzhiyun }
1511*4882a593Smuzhiyun static const struct dev_pm_ops rsi_pm_ops = {
1512*4882a593Smuzhiyun .suspend = rsi_suspend,
1513*4882a593Smuzhiyun .resume_noirq = rsi_resume,
1514*4882a593Smuzhiyun .freeze = rsi_freeze,
1515*4882a593Smuzhiyun .thaw = rsi_thaw,
1516*4882a593Smuzhiyun .restore = rsi_restore,
1517*4882a593Smuzhiyun };
1518*4882a593Smuzhiyun #endif
1519*4882a593Smuzhiyun
1520*4882a593Smuzhiyun static const struct sdio_device_id rsi_dev_table[] = {
1521*4882a593Smuzhiyun { SDIO_DEVICE(SDIO_VENDOR_ID_RSI, SDIO_DEVICE_ID_RSI_9113) },
1522*4882a593Smuzhiyun { SDIO_DEVICE(SDIO_VENDOR_ID_RSI, SDIO_DEVICE_ID_RSI_9116) },
1523*4882a593Smuzhiyun { /* Blank */},
1524*4882a593Smuzhiyun };
1525*4882a593Smuzhiyun
1526*4882a593Smuzhiyun static struct sdio_driver rsi_driver = {
1527*4882a593Smuzhiyun .name = "RSI-SDIO WLAN",
1528*4882a593Smuzhiyun .probe = rsi_probe,
1529*4882a593Smuzhiyun .remove = rsi_disconnect,
1530*4882a593Smuzhiyun .id_table = rsi_dev_table,
1531*4882a593Smuzhiyun #ifdef CONFIG_PM
1532*4882a593Smuzhiyun .drv = {
1533*4882a593Smuzhiyun .pm = &rsi_pm_ops,
1534*4882a593Smuzhiyun .shutdown = rsi_shutdown,
1535*4882a593Smuzhiyun }
1536*4882a593Smuzhiyun #endif
1537*4882a593Smuzhiyun };
1538*4882a593Smuzhiyun
1539*4882a593Smuzhiyun /**
1540*4882a593Smuzhiyun * rsi_module_init() - This function registers the sdio module.
1541*4882a593Smuzhiyun * @void: Void.
1542*4882a593Smuzhiyun *
1543*4882a593Smuzhiyun * Return: 0 on success.
1544*4882a593Smuzhiyun */
rsi_module_init(void)1545*4882a593Smuzhiyun static int rsi_module_init(void)
1546*4882a593Smuzhiyun {
1547*4882a593Smuzhiyun int ret;
1548*4882a593Smuzhiyun
1549*4882a593Smuzhiyun ret = sdio_register_driver(&rsi_driver);
1550*4882a593Smuzhiyun rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__);
1551*4882a593Smuzhiyun return ret;
1552*4882a593Smuzhiyun }
1553*4882a593Smuzhiyun
1554*4882a593Smuzhiyun /**
1555*4882a593Smuzhiyun * rsi_module_exit() - This function unregisters the sdio module.
1556*4882a593Smuzhiyun * @void: Void.
1557*4882a593Smuzhiyun *
1558*4882a593Smuzhiyun * Return: None.
1559*4882a593Smuzhiyun */
rsi_module_exit(void)1560*4882a593Smuzhiyun static void rsi_module_exit(void)
1561*4882a593Smuzhiyun {
1562*4882a593Smuzhiyun sdio_unregister_driver(&rsi_driver);
1563*4882a593Smuzhiyun rsi_dbg(INFO_ZONE, "%s: Unregistering driver\n", __func__);
1564*4882a593Smuzhiyun }
1565*4882a593Smuzhiyun
1566*4882a593Smuzhiyun module_init(rsi_module_init);
1567*4882a593Smuzhiyun module_exit(rsi_module_exit);
1568*4882a593Smuzhiyun
1569*4882a593Smuzhiyun MODULE_AUTHOR("Redpine Signals Inc");
1570*4882a593Smuzhiyun MODULE_DESCRIPTION("Common SDIO layer for RSI drivers");
1571*4882a593Smuzhiyun MODULE_SUPPORTED_DEVICE("RSI-91x");
1572*4882a593Smuzhiyun MODULE_DEVICE_TABLE(sdio, rsi_dev_table);
1573*4882a593Smuzhiyun MODULE_FIRMWARE(FIRMWARE_RSI9113);
1574*4882a593Smuzhiyun MODULE_VERSION("0.1");
1575*4882a593Smuzhiyun MODULE_LICENSE("Dual BSD/GPL");
1576