Linux Audio

Check our new training course

Loading...
v6.8
 1/*
 2 * Copyright (c) 2014 Redpine Signals Inc.
 3 *
 4 * Permission to use, copy, modify, and/or distribute this software for any
 5 * purpose with or without fee is hereby granted, provided that the above
 6 * copyright notice and this permission notice appear in all copies.
 7 *
 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 */
17
18#include <linux/firmware.h>
19#include "rsi_usb.h"
20
21/**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22 * rsi_usb_rx_thread() - This is a kernel thread to receive the packets from
23 *			 the USB device.
24 * @common: Pointer to the driver private structure.
25 *
26 * Return: None.
27 */
28void rsi_usb_rx_thread(struct rsi_common *common)
29{
30	struct rsi_hw *adapter = common->priv;
31	struct rsi_91x_usbdev *dev = adapter->rsi_dev;
32	int status;
33	struct sk_buff *skb;
34
35	do {
36		rsi_wait_event(&dev->rx_thread.event, EVENT_WAIT_FOREVER);
37		rsi_reset_event(&dev->rx_thread.event);
38
39		while (true) {
40			if (atomic_read(&dev->rx_thread.thread_done))
41				goto out;
42
43			skb = skb_dequeue(&dev->rx_q);
44			if (!skb)
45				break;
46			status = rsi_read_pkt(common, skb->data, 0);
47			if (status) {
48				rsi_dbg(ERR_ZONE, "%s: Failed To read data",
49					__func__);
50				break;
51			}
52			dev_kfree_skb(skb);
 
 
53		}
54	} while (1);
55
56out:
57	rsi_dbg(INFO_ZONE, "%s: Terminated thread\n", __func__);
58	skb_queue_purge(&dev->rx_q);
59	kthread_complete_and_exit(&dev->rx_thread.completion, 0);
60}
61
v4.10.11
  1/**
  2 * Copyright (c) 2014 Redpine Signals Inc.
  3 *
  4 * Permission to use, copy, modify, and/or distribute this software for any
  5 * purpose with or without fee is hereby granted, provided that the above
  6 * copyright notice and this permission notice appear in all copies.
  7 *
  8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 15 *
 16 */
 17
 18#include <linux/firmware.h>
 19#include "rsi_usb.h"
 20
 21/**
 22 * rsi_copy_to_card() - This function includes the actual funtionality of
 23 *			copying the TA firmware to the card.Basically this
 24 *			function includes opening the TA file,reading the TA
 25 *			file and writing their values in blocks of data.
 26 * @common: Pointer to the driver private structure.
 27 * @fw: Pointer to the firmware value to be written.
 28 * @len: length of firmware file.
 29 * @num_blocks: Number of blocks to be written to the card.
 30 *
 31 * Return: 0 on success and -1 on failure.
 32 */
 33static int rsi_copy_to_card(struct rsi_common *common,
 34			    const u8 *fw,
 35			    u32 len,
 36			    u32 num_blocks)
 37{
 38	struct rsi_hw *adapter = common->priv;
 39	struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
 40	u32 indx, ii;
 41	u32 block_size = dev->tx_blk_size;
 42	u32 lsb_address;
 43	u32 base_address;
 44
 45	base_address = TA_LOAD_ADDRESS;
 46
 47	for (indx = 0, ii = 0; ii < num_blocks; ii++, indx += block_size) {
 48		lsb_address = base_address;
 49		if (rsi_usb_write_register_multiple(adapter,
 50						    lsb_address,
 51						    (u8 *)(fw + indx),
 52						    block_size)) {
 53			rsi_dbg(ERR_ZONE,
 54				"%s: Unable to load %s blk\n", __func__,
 55				FIRMWARE_RSI9113);
 56			return -EIO;
 57		}
 58		rsi_dbg(INIT_ZONE, "%s: loading block: %d\n", __func__, ii);
 59		base_address += block_size;
 60	}
 61
 62	if (len % block_size) {
 63		lsb_address = base_address;
 64		if (rsi_usb_write_register_multiple(adapter,
 65						    lsb_address,
 66						    (u8 *)(fw + indx),
 67						    len % block_size)) {
 68			rsi_dbg(ERR_ZONE,
 69				"%s: Unable to load %s blk\n", __func__,
 70				FIRMWARE_RSI9113);
 71			return -EIO;
 72		}
 73	}
 74	rsi_dbg(INIT_ZONE,
 75		"%s: Succesfully loaded %s instructions\n", __func__,
 76		FIRMWARE_RSI9113);
 77
 78	rsi_dbg(INIT_ZONE, "%s: loaded firmware\n", __func__);
 79	return 0;
 80}
 81
 82/**
 83 * rsi_usb_rx_thread() - This is a kernel thread to receive the packets from
 84 *			 the USB device.
 85 * @common: Pointer to the driver private structure.
 86 *
 87 * Return: None.
 88 */
 89void rsi_usb_rx_thread(struct rsi_common *common)
 90{
 91	struct rsi_hw *adapter = common->priv;
 92	struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
 93	int status;
 
 94
 95	do {
 96		rsi_wait_event(&dev->rx_thread.event, EVENT_WAIT_FOREVER);
 
 97
 98		if (atomic_read(&dev->rx_thread.thread_done))
 99			goto out;
100
101		mutex_lock(&common->tx_rxlock);
102		status = rsi_read_pkt(common, 0);
103		if (status) {
104			rsi_dbg(ERR_ZONE, "%s: Failed To read data", __func__);
105			mutex_unlock(&common->tx_rxlock);
106			return;
107		}
108		mutex_unlock(&common->tx_rxlock);
109		rsi_reset_event(&dev->rx_thread.event);
110		if (adapter->rx_urb_submit(adapter)) {
111			rsi_dbg(ERR_ZONE,
112				"%s: Failed in urb submission", __func__);
113			return;
114		}
115	} while (1);
116
117out:
118	rsi_dbg(INFO_ZONE, "%s: Terminated thread\n", __func__);
119	complete_and_exit(&dev->rx_thread.completion, 0);
 
120}
121
122
123/**
124 * rsi_load_ta_instructions() - This function includes the actual funtionality
125 *				of loading the TA firmware.This function also
126 *				includes opening the TA file,reading the TA
127 *				file and writing their value in blocks of data.
128 * @common: Pointer to the driver private structure.
129 *
130 * Return: status: 0 on success, -1 on failure.
131 */
132static int rsi_load_ta_instructions(struct rsi_common *common)
133{
134	struct rsi_hw *adapter = common->priv;
135	struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
136	const struct firmware *fw_entry = NULL;
137	u32 block_size = dev->tx_blk_size;
138	const u8 *fw;
139	u32 num_blocks, len;
140	int status = 0;
141
142	status = request_firmware(&fw_entry, FIRMWARE_RSI9113, adapter->device);
143	if (status < 0) {
144		rsi_dbg(ERR_ZONE, "%s Firmware file %s not found\n",
145			__func__, FIRMWARE_RSI9113);
146		return status;
147	}
148
149	/* Copy firmware into DMA-accessible memory */
150	fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
151	if (!fw) {
152		status = -ENOMEM;
153		goto out;
154	}
155	len = fw_entry->size;
156
157	if (len % 4)
158		len += (4 - (len % 4));
159
160	num_blocks = (len / block_size);
161
162	rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len);
163	rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks);
164
165	status = rsi_copy_to_card(common, fw, len, num_blocks);
166	kfree(fw);
167
168out:
169	release_firmware(fw_entry);
170	return status;
171}
172
173/**
174 * rsi_device_init() - This Function Initializes The HAL.
175 * @common: Pointer to the driver private structure.
176 *
177 * Return: 0 on success, -1 on failure.
178 */
179int rsi_usb_device_init(struct rsi_common *common)
180{
181	if (rsi_load_ta_instructions(common))
182		return -EIO;
183
184	return 0;
185		}