// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
// Copyright(c) 2023 Intel Corporation
/*
* Soundwire Intel ops for LunarLake
*/
#include <linux/acpi.h>
#include <linux/cleanup.h>
#include <linux/device.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_intel.h>
#include <linux/string_choices.h>
#include <sound/hdaudio.h>
#include <sound/hda-mlink.h>
#include <sound/hda-sdw-bpt.h>
#include <sound/hda_register.h>
#include <sound/pcm_params.h>
#include "cadence_master.h"
#include "bus.h"
#include "intel.h"
static int sdw_slave_bpt_stream_add(struct sdw_slave *slave, struct sdw_stream_runtime *stream)
{
struct sdw_stream_config sconfig = {0};
struct sdw_port_config pconfig = {0};
int ret;
/* arbitrary configuration */
sconfig.frame_rate = 16000;
sconfig.ch_count = 1;
sconfig.bps = 32; /* this is required for BPT/BRA */
sconfig.direction = SDW_DATA_DIR_RX;
sconfig.type = SDW_STREAM_BPT;
pconfig.num = 0;
pconfig.ch_mask = BIT(0);
ret = sdw_stream_add_slave(slave, &sconfig, &pconfig, 1, stream);
if (ret)
dev_err(&slave->dev, "%s: failed: %d\n", __func__, ret);
return ret;
}
#define READ_PDI1_MIN_SIZE 12
static int intel_ace2x_bpt_open_stream(struct sdw_intel *sdw, struct sdw_slave *slave,
struct sdw_bpt_msg *msg)
{
struct sdw_cdns *cdns = &sdw->cdns;
struct sdw_bus *bus = &cdns->bus;
struct sdw_master_prop *prop = &bus->prop;
struct sdw_stream_runtime *stream;
struct sdw_stream_config sconfig;
struct sdw_port_config *pconfig;
unsigned int pdi0_buf_size_pre_frame;
unsigned int pdi1_buf_size_pre_frame;
unsigned int pdi0_buffer_size_;
unsigned int pdi1_buffer_size_;
unsigned int pdi0_buffer_size;
unsigned int tx_dma_bandwidth;
unsigned int pdi1_buffer_size;
unsigned int rx_dma_bandwidth;
unsigned int fake_num_frames;
unsigned int data_per_frame;
unsigned int tx_total_bytes;
struct sdw_cdns_pdi *pdi0;
struct sdw_cdns_pdi *pdi1;
unsigned int rx_alignment;
unsigned int tx_alignment;
unsigned int num_frames_;
unsigned int num_frames;
unsigned int fake_size;
unsigned int tx_pad;
unsigned int rx_pad;
int command;
int ret1;
int ret;
int dir;
int len;
int i;
stream = sdw_alloc_stream("BPT", SDW_STREAM_BPT);
if (!stream)
return -ENOMEM;
cdns->bus.bpt_stream = stream;
ret = sdw_slave_bpt_stream_add(slave, stream);
if (ret < 0)
goto release_stream;
/* handle PDI0 first */
dir = SDW_DATA_DIR_TX;
pdi0 = sdw_cdns_alloc_pdi(cdns, &cdns->pcm, 1, dir, 0);
if (!pdi0) {
dev_err(cdns->dev, "%s: sdw_cdns_alloc_pdi0 failed\n&quo