/ src / drivers / soundwire / alc711 / alc711.c
alc711.c
  1  /* SPDX-License-Identifier: GPL-2.0-only */
  2  
  3  #include <acpi/acpigen.h>
  4  #include <acpi/acpi_device.h>
  5  #include <acpi/acpi_soundwire.h>
  6  #include <device/device.h>
  7  #include <device/soundwire.h>
  8  #include <mipi/ids.h>
  9  #include <stdio.h>
 10  
 11  #include "chip.h"
 12  
 13  static struct soundwire_slave alc711_slave = {
 14  	.wake_up_unavailable = false,
 15  	.test_mode_supported = false,
 16  	.clock_stop_mode1_supported = true,
 17  	.simplified_clockstopprepare_sm_supported = true,
 18  	.clockstopprepare_hard_reset_behavior = false,
 19  	.highPHY_capable = false,
 20  	.paging_supported = false,
 21  	.bank_delay_supported = false,
 22  	.port15_read_behavior = false,
 23  	.source_port_list = SOUNDWIRE_PORT(2),
 24  	.sink_port_list = SOUNDWIRE_PORT(1),
 25  };
 26  
 27  static struct soundwire_audio_mode alc711_audio_mode = {
 28  	/* Bus frequency must be 1/2/4/8 divider of supported input frequencies. */
 29  	.bus_frequency_configs_count = 12,
 30  	.bus_frequency_configs = {
 31  		9600 * KHz,
 32  		4800 * KHz,
 33  		2400 * KHz,
 34  		1200 * KHz,
 35  		12000 * KHz,
 36  		6000 * KHz,
 37  		3000 * KHz,
 38  		1500 * KHz,
 39  		12288 * KHz,
 40  		6144 * KHz,
 41  		3072 * KHz,
 42  		1536 * KHz
 43  	},
 44  	/* Support 16 KHz to 192 KHz sampling frequency */
 45  	.sampling_frequency_configs_count = 9,
 46  	.sampling_frequency_configs = {
 47  		16 * KHz,
 48  		22.05 * KHz,
 49  		24 * KHz,
 50  		32 * KHz,
 51  		44.1 * KHz,
 52  		48 * KHz,
 53  		88.2 * KHz,
 54  		96 * KHz,
 55  		192 * KHz
 56  	},
 57  	.prepare_channel_behavior = CHANNEL_PREPARE_ANY_FREQUENCY
 58  };
 59  
 60  static struct soundwire_dpn alc711_dp = {
 61  	.port_wordlength_configs_count = 1,
 62  	.port_wordlength_configs = { 32 },
 63  	.data_port_type = FULL_DATA_PORT,
 64  	.max_grouping_supported = BLOCK_GROUP_COUNT_1,
 65  	.simplified_channelprepare_sm = false,
 66  	.imp_def_dpn_interrupts_supported = 0,
 67  	.min_channel_number = 1,
 68  	.max_channel_number = 2,
 69  	.modes_supported = MODE_ISOCHRONOUS | MODE_TX_CONTROLLED |
 70  			   MODE_RX_CONTROLLED | MODE_FULL_ASYNCHRONOUS,
 71  	.block_packing_mode = true,
 72  	.port_audio_mode_count = 1,
 73  	.port_audio_mode_list = { 0 }
 74  };
 75  
 76  static const struct soundwire_codec alc711_codec = {
 77  	.slave = &alc711_slave,
 78  	.audio_mode = { &alc711_audio_mode },
 79  	.dpn = {
 80  		{
 81  			/* Data Input for Speaker Path */
 82  			.port = 1,
 83  			.sink = &alc711_dp
 84  		},
 85  		{
 86  			/* Data Output for DSP Path */
 87  			.port = 2,
 88  			.source = &alc711_dp
 89  		}
 90  	}
 91  
 92  };
 93  
 94  static void soundwire_alc711_fill_ssdt(const struct device *dev)
 95  {
 96  	struct drivers_soundwire_alc711_config *config = dev->chip_info;
 97  	const char *scope = acpi_device_scope(dev);
 98  	struct acpi_dp *dsd;
 99  
100  	if (!scope)
101  		return;
102  
103  	acpigen_write_scope(scope);
104  	acpigen_write_device(acpi_device_name(dev));
105  
106  	/* Set codec address IDs. */
107  	config->alc711_address.link_id = dev->path.generic.id;
108  	config->alc711_address.unique_id = dev->path.generic.subid;
109  	config->alc711_address.manufacturer_id = MIPI_MFG_ID_REALTEK;
110  
111  	acpigen_write_ADR_soundwire_device(&config->alc711_address);
112  	acpigen_write_name_string("_DDN", config->desc ? : dev->chip_ops->name);
113  	acpigen_write_STA(acpi_device_status(dev));
114  
115  	dsd = acpi_dp_new_table("_DSD");
116  	soundwire_gen_codec(dsd, &alc711_codec, NULL);
117  	acpi_dp_write(dsd);
118  
119  	acpigen_pop_len(); /* Device */
120  	acpigen_pop_len(); /* Scope */
121  }
122  
123  static const char *soundwire_alc711_acpi_name(const struct device *dev)
124  {
125  	struct drivers_soundwire_alc711_config *config = dev->chip_info;
126  	static char name[5];
127  
128  	if (config->name)
129  		return config->name;
130  	snprintf(name, sizeof(name), "SW%1X%1X", dev->path.generic.id, dev->path.generic.subid);
131  	return name;
132  }
133  
134  static struct device_operations soundwire_alc711_ops = {
135  	.read_resources		= noop_read_resources,
136  	.set_resources		= noop_set_resources,
137  	.acpi_name		= soundwire_alc711_acpi_name,
138  	.acpi_fill_ssdt		= soundwire_alc711_fill_ssdt,
139  };
140  
141  static void soundwire_alc711_enable(struct device *dev)
142  {
143  	dev->ops = &soundwire_alc711_ops;
144  }
145  
146  struct chip_operations drivers_soundwire_alc711_ops = {
147  #if CONFIG(DRIVERS_SOUNDWIRE_ALC_BASE_7XX)
148  	.name = "Realtek ALC 7 Series SoundWire Codec",
149  #else
150  	.name = "Unknown",
151  #endif
152  	.enable_dev = soundwire_alc711_enable
153  };