Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions audioreach-driver/audioreach_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
#include <sound/jack.h>
#include <linux/input-event-codes.h>
#include <sound/simple_card_utils.h>
#include "q6afe.h"
#include "sdw.h"
#include "q6prm_audioreach.h"

#define AFE_PORT_MAX 137
#define NAME_SIZE 32

struct qcs6490_snd_data {
Expand Down
56 changes: 56 additions & 0 deletions audioreach-driver/q6apm_audio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* SPDX-License-Identifier: GPL-2.0 */
// Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.

#ifndef __Q6APM_AUDIO_H__
#define __Q6APM_AUDIO_H__

#include <sound/soc.h>

#define AR_PCM_MAX_NUM_CHANNEL 8

struct audioreach_module_config {
int direction;
u32 sample_rate;
u16 bit_width;
u16 bits_per_sample;

u16 data_format;
u16 num_channels;
u16 dp_idx;
u32 channel_allocation;
u32 sd_line_mask;
int fmt;
struct snd_codec codec;
u8 channel_map[AR_PCM_MAX_NUM_CHANNEL];
};

struct q6dsp_audio_port_dai_driver_config {
int (*probe)(struct snd_soc_dai *dai);
int (*remove)(struct snd_soc_dai *dai);
const struct snd_soc_dai_ops *q6hdmi_ops;
const struct snd_soc_dai_ops *q6slim_ops;
const struct snd_soc_dai_ops *q6i2s_ops;
const struct snd_soc_dai_ops *q6tdm_ops;
const struct snd_soc_dai_ops *q6dma_ops;
const struct snd_soc_dai_ops *q6usb_ops;
};

struct apm_cmd_header {
uint32_t payload_address_lsw;
uint32_t payload_address_msw;
uint32_t mem_map_handle;
uint32_t payload_size;
} __packed;

#define APM_CMD_HDR_SIZE sizeof(struct apm_cmd_header)

struct apm_module_param_data {
uint32_t module_instance_id;
uint32_t param_id;
uint32_t param_size;
uint32_t error_code;
} __packed;

#define APM_MODULE_PARAM_DATA_SIZE sizeof(struct apm_module_param_data)

#endif
3 changes: 2 additions & 1 deletion audioreach-driver/q6apm_audio_mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@
#include <linux/firmware/qcom/qcom_scm.h>
#include <dt-bindings/firmware/qcom,scm.h>
#include <sound/soc.h>
#include "q6prm_audioreach.h"
#include <linux/msm_audio.h>
#include "q6apm_audio.h"
#include "q6prm_audioreach.h"

#define DRV_NAME "q6apm-audio-mem"

Expand Down
64 changes: 37 additions & 27 deletions audioreach-driver/q6apm_audio_pkt.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,13 @@
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/pcm.h>
#include "audioreach.h"
#include "q6apm.h"
#include "q6apm_audio.h"
#include "q6prm_audioreach.h"

#define APM_MODULE_INSTANCE_ID 0x00000001
#define APM_CMD_CLOSE_ALL 0x01001013
#define APM_CMD_GET_SPF_STATE 0x01001021
#define APM_CMD_RSP_GET_SPF_STATE 0x02001007
#define APM_CMD_SHARED_MEM_MAP_REGIONS 0x0100100C
#define APM_MEMORY_MAP_BIT_MASK_IS_OFFSET_MODE 0x00000004UL

Expand All @@ -54,7 +57,6 @@ do { \
#define MODULE_NAME "audio-pkt"
#define MINOR_NUMBER_COUNT 1
#define AUDPKT_DRIVER_NAME "aud_pasthru_adsp"
#define APM_AUDIO_DRV_NAME "q6apm-audio-pkt"

struct q6apm_audio_pkt {
struct device *dev;
Expand All @@ -64,10 +66,8 @@ struct q6apm_audio_pkt {
//wait_queue_head_t wait;
struct gpr_ibasic_rsp_result_t result;

struct mutex cmd_lock;
uint32_t state;


struct cdev cdev;
struct mutex lock;
spinlock_t queue_lock;
Expand Down Expand Up @@ -319,7 +319,6 @@ static ssize_t audio_pkt_read(struct file *file, char __user *buf,
unsigned long flags;
struct sk_buff *skb;
int use;
uint32_t *temp;

if (!audpkt_dev) {
AUDIO_PKT_ERR("invalid device handle\n");
Expand Down Expand Up @@ -350,7 +349,6 @@ static ssize_t audio_pkt_read(struct file *file, char __user *buf,
use = min_t(size_t, count, skb->len);
if (copy_to_user(buf, skb->data, use))
use = -EFAULT;
temp = (uint32_t *) skb->data;
kfree_skb(skb);

return use;
Expand Down Expand Up @@ -421,6 +419,7 @@ static ssize_t audio_pkt_write(struct file *file, const char __user *buf,
ret = audpkt_chk_and_update_physical_addr((struct audio_gpr_pkt *) audpkt_hdr);
if (ret < 0) {
AUDIO_PKT_ERR("Update Physical Address Failed -%d\n", ret);
kfree(kbuf);
return ret;
}
}
Expand Down Expand Up @@ -456,6 +455,8 @@ static ssize_t audio_pkt_write(struct file *file, const char __user *buf,
ret = gpr_send_pkt(audpkt_dev->adev, (struct gpr_pkt *) kbuf);
if (ret < 0) {
AUDIO_PKT_ERR("APR Send Packet Failed ret -%d\n", ret);
mutex_unlock(&audpkt_dev->lock);
kfree(kbuf);
return ret;
}
mutex_unlock(&audpkt_dev->lock);
Expand All @@ -480,7 +481,6 @@ static unsigned int audio_pkt_poll(struct file *file, poll_table *wait)
unsigned int mask = 0;
unsigned long flags;

audpkt_dev = file->private_data;
if (!audpkt_dev) {
AUDIO_PKT_ERR("invalid device handle\n");
return POLLERR;
Expand Down Expand Up @@ -584,7 +584,7 @@ static int q6apm_audio_pkt_probe(gpr_device_t *adev)
err_device:
class_destroy(apm->audio_pkt_class);
err_class:
unregister_chrdev_region(MAJOR(apm->audio_pkt_major),
unregister_chrdev_region(apm->audio_pkt_major,
MINOR_NUMBER_COUNT);
err_chrdev:
return ret;
Expand All @@ -596,13 +596,17 @@ static int q6apm_audio_pkt_callback(struct gpr_resp_pkt *data, void *priv, int o
struct q6apm_audio_pkt *apm = dev_get_drvdata(&gdev->dev);
struct gpr_ibasic_rsp_result_t *result;
struct gpr_hdr *hdr = &data->hdr;
uint8_t *pkt = NULL;
struct device *dev = &gdev->dev;
uint16_t hdr_size, pkt_size;
unsigned long flags;
struct sk_buff *skb;
int ret;
struct gpr_port_map *audpkt_port_map;

if (!apm) {
dev_dbg(dev, "callback with NULL drvdata\n");
return -ENODEV;
}

hdr_size = hdr->hdr_size * 4;
pkt_size = hdr->pkt_size;
Expand All @@ -616,24 +620,17 @@ static int q6apm_audio_pkt_callback(struct gpr_resp_pkt *data, void *priv, int o
idr_remove(&apm->audpkt_port_idr, hdr->token);
kfree(audpkt_port_map);
} else {
AUDIO_PKT_ERR("Token=%u not found\n", hdr->token);
dev_dbg(dev, "Token=%u not found\n", hdr->token);
}
mutex_unlock(&apm->audpkt_port_lock);

pkt = kmalloc(pkt_size, GFP_KERNEL);
if (!pkt)
return -ENOMEM;

memcpy(pkt, (uint8_t *)data, hdr_size);
memcpy(pkt + hdr_size, (uint8_t *)data->payload, pkt_size - hdr_size);

skb = alloc_skb(pkt_size, GFP_ATOMIC);
if (!skb)
return -ENOMEM;

skb_put_data(skb, (void *)pkt, pkt_size);
skb_put_data(skb, (uint8_t *)data, hdr_size);
skb_put_data(skb, (uint8_t *)data->payload, pkt_size - hdr_size);

kfree(pkt);
spin_lock_irqsave(&apm->queue_lock, flags);
skb_queue_tail(&apm->queue, skb);
spin_unlock_irqrestore(&apm->queue_lock, flags);
Expand All @@ -642,19 +639,32 @@ static int q6apm_audio_pkt_callback(struct gpr_resp_pkt *data, void *priv, int o
/* wake up any blocking processes, waiting for new data */
wake_up_interruptible(&apm->readq);
if(hdr->opcode == APM_CMD_RSP_GET_SPF_STATE) {
result = data->payload;
apm->result.opcode = hdr->opcode;
apm->result.status = 0;
/* First word of result it state */
apm->state = hdr->opcode;
}
result = data->payload;
apm->result.opcode = hdr->opcode;
apm->result.status = 0;
/* First word of result it state */
apm->state = hdr->opcode;
}

return 0;
}

static void q6apm_audio_pkt_remove(gpr_device_t *adev)
{
of_platform_depopulate(&adev->dev);
struct device *dev = &adev->dev;
struct q6apm_audio_pkt *apm = dev_get_drvdata(dev);

of_platform_depopulate(dev);

if (!apm)
return;

cdev_del(&apm->cdev);
device_destroy(apm->audio_pkt_class, apm->audio_pkt_major);
class_destroy(apm->audio_pkt_class);
unregister_chrdev_region(apm->audio_pkt_major, MINOR_NUMBER_COUNT);

dev_set_drvdata(dev, NULL);
}

#ifdef CONFIG_OF
Expand Down
Loading
Loading