2 * rt5677-spi.c -- RT5677 ALSA SoC audio codec driver
4 * Copyright 2013 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
12 #include <linux/module.h>
13 #include <linux/input.h>
14 #include <linux/spi/spi.h>
15 #include <linux/device.h>
16 #include <linux/init.h>
17 #include <linux/delay.h>
18 #include <linux/interrupt.h>
19 #include <linux/irq.h>
20 #include <linux/slab.h>
21 #include <linux/gpio.h>
22 #include <linux/sched.h>
23 #include <linux/kthread.h>
24 #include <linux/uaccess.h>
25 #include <linux/miscdevice.h>
26 #include <linux/regulator/consumer.h>
27 #include <linux/pm_qos.h>
28 #include <linux/sysfs.h>
29 #include <linux/clk.h>
30 #include <linux/firmware.h>
32 #include "rt5677-spi.h"
34 static struct spi_device
*g_spi
;
37 * rt5677_spi_write - Write data to SPI.
38 * @txbuf: Data Buffer for writing.
42 * Returns true for success.
44 int rt5677_spi_write(u8
*txbuf
, size_t len
)
48 status
= spi_write(g_spi
, txbuf
, len
);
51 dev_err(&g_spi
->dev
, "rt5677_spi_write error %d\n", status
);
55 EXPORT_SYMBOL_GPL(rt5677_spi_write
);
58 * rt5677_spi_burst_write - Write data to SPI by rt5677 dsp memory address.
59 * @addr: Start address.
60 * @txbuf: Data Buffer for writng.
61 * @len: Data length, it must be a multiple of 8.
64 * Returns true for success.
66 int rt5677_spi_burst_write(u32 addr
, const struct firmware
*fw
)
68 u8 spi_cmd
= RT5677_SPI_CMD_BURST_WRITE
;
70 unsigned int i
, end
, offset
= 0;
72 write_buf
= kmalloc(RT5677_SPI_BUF_LEN
+ 6, GFP_KERNEL
);
74 if (write_buf
== NULL
)
77 while (offset
< fw
->size
) {
78 if (offset
+ RT5677_SPI_BUF_LEN
<= fw
->size
)
79 end
= RT5677_SPI_BUF_LEN
;
81 end
= fw
->size
% RT5677_SPI_BUF_LEN
;
83 write_buf
[0] = spi_cmd
;
84 write_buf
[1] = ((addr
+ offset
) & 0xff000000) >> 24;
85 write_buf
[2] = ((addr
+ offset
) & 0x00ff0000) >> 16;
86 write_buf
[3] = ((addr
+ offset
) & 0x0000ff00) >> 8;
87 write_buf
[4] = ((addr
+ offset
) & 0x000000ff) >> 0;
89 for (i
= 0; i
< end
; i
+= 8) {
90 write_buf
[i
+ 12] = fw
->data
[offset
+ i
+ 0];
91 write_buf
[i
+ 11] = fw
->data
[offset
+ i
+ 1];
92 write_buf
[i
+ 10] = fw
->data
[offset
+ i
+ 2];
93 write_buf
[i
+ 9] = fw
->data
[offset
+ i
+ 3];
94 write_buf
[i
+ 8] = fw
->data
[offset
+ i
+ 4];
95 write_buf
[i
+ 7] = fw
->data
[offset
+ i
+ 5];
96 write_buf
[i
+ 6] = fw
->data
[offset
+ i
+ 6];
97 write_buf
[i
+ 5] = fw
->data
[offset
+ i
+ 7];
100 write_buf
[end
+ 5] = spi_cmd
;
102 rt5677_spi_write(write_buf
, end
+ 6);
104 offset
+= RT5677_SPI_BUF_LEN
;
111 EXPORT_SYMBOL_GPL(rt5677_spi_burst_write
);
113 static int rt5677_spi_probe(struct spi_device
*spi
)
119 static struct spi_driver rt5677_spi_driver
= {
122 .owner
= THIS_MODULE
,
124 .probe
= rt5677_spi_probe
,
126 module_spi_driver(rt5677_spi_driver
);
128 MODULE_DESCRIPTION("ASoC RT5677 SPI driver");
129 MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
130 MODULE_LICENSE("GPL v2");