Skip to content

Commit

Permalink
ASoC: rt5677: Support DSP function for VAD application
Browse files Browse the repository at this point in the history
The ALC5677 has a programmable DSP, and there is a SPI that is dadicated for DSP
firmware loading. Therefore, the patch includes a SPI driver for writing the DSP
firmware. The VAD(Voice Activaty Detection) has be implemented and use the DSP to
recognize the key phase.

Signed-off-by: Oder Chiou <oder_chiou@realtek.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Oder Chiou authored and Mark Brown committed Oct 20, 2014
1 parent 40eb90a commit af48f1d
Show file tree
Hide file tree
Showing 5 changed files with 440 additions and 5 deletions.
2 changes: 1 addition & 1 deletion sound/soc/codecs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ snd-soc-rt5640-objs := rt5640.o
snd-soc-rt5645-objs := rt5645.o
snd-soc-rt5651-objs := rt5651.o
snd-soc-rt5670-objs := rt5670.o
snd-soc-rt5677-objs := rt5677.o
snd-soc-rt5677-objs := rt5677.o rt5677-spi.o
snd-soc-sgtl5000-objs := sgtl5000.o
snd-soc-alc5623-objs := alc5623.o
snd-soc-alc5632-objs := alc5632.o
Expand Down
128 changes: 128 additions & 0 deletions sound/soc/codecs/rt5677-spi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* rt5677-spi.c -- RT5677 ALSA SoC audio codec driver
*
* Copyright 2013 Realtek Semiconductor Corp.
* Author: Oder Chiou <oder_chiou@realtek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/module.h>
#include <linux/input.h>
#include <linux/spi/spi.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_qos.h>
#include <linux/sysfs.h>
#include <linux/clk.h>
#include <linux/firmware.h>

#include "rt5677-spi.h"

static struct spi_device *g_spi;

/**
* rt5677_spi_write - Write data to SPI.
* @txbuf: Data Buffer for writing.
* @len: Data length.
*
*
* Returns true for success.
*/
int rt5677_spi_write(u8 *txbuf, size_t len)
{
int status;

status = spi_write(g_spi, txbuf, len);

if (status)
dev_err(&g_spi->dev, "rt5677_spi_write error %d\n", status);

return status;
}

/**
* rt5677_spi_burst_write - Write data to SPI by rt5677 dsp memory address.
* @addr: Start address.
* @txbuf: Data Buffer for writng.
* @len: Data length, it must be a multiple of 8.
*
*
* Returns true for success.
*/
int rt5677_spi_burst_write(u32 addr, const struct firmware *fw)
{
u8 spi_cmd = RT5677_SPI_CMD_BURST_WRITE;
u8 *write_buf;
unsigned int i, end, offset = 0;

write_buf = kmalloc(RT5677_SPI_BUF_LEN + 6, GFP_KERNEL);

if (write_buf == NULL)
return -ENOMEM;

while (offset < fw->size) {
if (offset + RT5677_SPI_BUF_LEN <= fw->size)
end = RT5677_SPI_BUF_LEN;
else
end = fw->size % RT5677_SPI_BUF_LEN;

write_buf[0] = spi_cmd;
write_buf[1] = ((addr + offset) & 0xff000000) >> 24;
write_buf[2] = ((addr + offset) & 0x00ff0000) >> 16;
write_buf[3] = ((addr + offset) & 0x0000ff00) >> 8;
write_buf[4] = ((addr + offset) & 0x000000ff) >> 0;

for (i = 0; i < end; i += 8) {
write_buf[i + 12] = fw->data[offset + i + 0];
write_buf[i + 11] = fw->data[offset + i + 1];
write_buf[i + 10] = fw->data[offset + i + 2];
write_buf[i + 9] = fw->data[offset + i + 3];
write_buf[i + 8] = fw->data[offset + i + 4];
write_buf[i + 7] = fw->data[offset + i + 5];
write_buf[i + 6] = fw->data[offset + i + 6];
write_buf[i + 5] = fw->data[offset + i + 7];
}

write_buf[end + 5] = spi_cmd;

rt5677_spi_write(write_buf, end + 6);

offset += RT5677_SPI_BUF_LEN;
}

kfree(write_buf);

return 0;
}

static int rt5677_spi_probe(struct spi_device *spi)
{
g_spi = spi;
return 0;
}

static struct spi_driver rt5677_spi_driver = {
.driver = {
.name = "rt5677",
.owner = THIS_MODULE,
},
.probe = rt5677_spi_probe,
};
module_spi_driver(rt5677_spi_driver);

MODULE_DESCRIPTION("ASoC RT5677 SPI driver");
MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
MODULE_LICENSE("GPL v2");
21 changes: 21 additions & 0 deletions sound/soc/codecs/rt5677-spi.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* rt5677-spi.h -- RT5677 ALSA SoC audio codec driver
*
* Copyright 2013 Realtek Semiconductor Corp.
* Author: Oder Chiou <oder_chiou@realtek.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#ifndef __RT5671_SPI_H__
#define __RT5671_SPI_H__

#define RT5677_SPI_BUF_LEN 240
#define RT5677_SPI_CMD_BURST_WRITE 0x05

int rt5677_spi_write(u8 *txbuf, size_t len);
int rt5677_spi_burst_write(u32 addr, const struct firmware *fw);

#endif /* __RT5677_SPI_H__ */
Loading

0 comments on commit af48f1d

Please sign in to comment.