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 };