Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0-only
  2// cs42l42-sdw.c -- CS42L42 ALSA SoC audio driver SoundWire driver
  3//
  4// Copyright (C) 2022 Cirrus Logic, Inc. and
  5//                    Cirrus Logic International Semiconductor Ltd.
  6
  7#include <linux/acpi.h>
  8#include <linux/device.h>
  9#include <linux/gpio/consumer.h>
 10#include <linux/iopoll.h>
 11#include <linux/module.h>
 12#include <linux/mod_devicetable.h>
 13#include <linux/of_irq.h>
 14#include <linux/pm_runtime.h>
 15#include <linux/soundwire/sdw.h>
 16#include <linux/soundwire/sdw_registers.h>
 17#include <linux/soundwire/sdw_type.h>
 18#include <sound/pcm.h>
 19#include <sound/pcm_params.h>
 20#include <sound/sdw.h>
 21#include <sound/soc.h>
 22
 23#include "cs42l42.h"
 24
 25#define CS42L42_SDW_CAPTURE_PORT	1
 26#define CS42L42_SDW_PLAYBACK_PORT	2
 27
 28/* Register addresses are offset when sent over SoundWire */
 29#define CS42L42_SDW_ADDR_OFFSET		0x8000
 30
 31#define CS42L42_SDW_MEM_ACCESS_STATUS	0xd0
 32#define CS42L42_SDW_MEM_READ_DATA	0xd8
 33
 34#define CS42L42_SDW_LAST_LATE		BIT(3)
 35#define CS42L42_SDW_CMD_IN_PROGRESS	BIT(2)
 36#define CS42L42_SDW_RDATA_RDY		BIT(0)
 37
 38#define CS42L42_DELAYED_READ_POLL_US	1
 39#define CS42L42_DELAYED_READ_TIMEOUT_US	100
 40
 41static const struct snd_soc_dapm_route cs42l42_sdw_audio_map[] = {
 42	/* Playback Path */
 43	{ "HP", NULL, "MIXER" },
 44	{ "MIXER", NULL, "DACSRC" },
 45	{ "DACSRC", NULL, "Playback" },
 46
 47	/* Capture Path */
 48	{ "ADCSRC", NULL, "HS" },
 49	{ "Capture", NULL, "ADCSRC" },
 50};
 51
 52static int cs42l42_sdw_dai_startup(struct snd_pcm_substream *substream,
 53				   struct snd_soc_dai *dai)
 54{
 55	struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component);
 56
 57	if (!cs42l42->init_done)
 58		return -ENODEV;
 59
 60	return 0;
 61}
 62
 63static int cs42l42_sdw_dai_hw_params(struct snd_pcm_substream *substream,
 64				     struct snd_pcm_hw_params *params,
 65				     struct snd_soc_dai *dai)
 66{
 67	struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component);
 68	struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
 69	struct sdw_stream_config stream_config = {0};
 70	struct sdw_port_config port_config = {0};
 71	int ret;
 72
 73	if (!sdw_stream)
 74		return -EINVAL;
 75
 76	/* Needed for PLL configuration when we are notified of new bus config */
 77	cs42l42->sample_rate = params_rate(params);
 78
 79	snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
 80
 81	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
 82		port_config.num = CS42L42_SDW_PLAYBACK_PORT;
 83	else
 84		port_config.num = CS42L42_SDW_CAPTURE_PORT;
 85
 86	ret = sdw_stream_add_slave(cs42l42->sdw_peripheral, &stream_config, &port_config, 1,
 87				   sdw_stream);
 88	if (ret) {
 89		dev_err(dai->dev, "Failed to add sdw stream: %d\n", ret);
 90		return ret;
 91	}
 92
 93	cs42l42_src_config(dai->component, params_rate(params));
 94
 95	return 0;
 96}
 97
 98static int cs42l42_sdw_dai_prepare(struct snd_pcm_substream *substream,
 99				   struct snd_soc_dai *dai)
100{
101	struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component);
102
103	dev_dbg(dai->dev, "dai_prepare: sclk=%u rate=%u\n", cs42l42->sclk, cs42l42->sample_rate);
104
105	if (!cs42l42->sclk || !cs42l42->sample_rate)
106		return -EINVAL;
107
108	/*
109	 * At this point we know the sample rate from hw_params, and the SWIRE_CLK from bus_config()
110	 * callback. This could only fail if the ACPI or machine driver are misconfigured to allow
111	 * an unsupported SWIRE_CLK and sample_rate combination.
112	 */
113
114	return cs42l42_pll_config(dai->component, cs42l42->sclk, cs42l42->sample_rate);
115}
116
117static int cs42l42_sdw_dai_hw_free(struct snd_pcm_substream *substream,
118				   struct snd_soc_dai *dai)
119{
120	struct cs42l42_private *cs42l42 = snd_soc_component_get_drvdata(dai->component);
121	struct sdw_stream_runtime *sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
122
123	sdw_stream_remove_slave(cs42l42->sdw_peripheral, sdw_stream);
124	cs42l42->sample_rate = 0;
125
126	return 0;
127}
128
129static int cs42l42_sdw_port_prep(struct sdw_slave *slave,
130				 struct sdw_prepare_ch *prepare_ch,
131				 enum sdw_port_prep_ops state)
132{
133	struct cs42l42_private *cs42l42 = dev_get_drvdata(&slave->dev);
134	unsigned int pdn_mask;
135
136	if (prepare_ch->num == CS42L42_SDW_PLAYBACK_PORT)
137		pdn_mask = CS42L42_HP_PDN_MASK;
138	else
139		pdn_mask = CS42L42_ADC_PDN_MASK;
140
141	if (state == SDW_OPS_PORT_PRE_PREP) {
142		dev_dbg(cs42l42->dev, "Prep Port pdn_mask:%x\n", pdn_mask);
143		regmap_clear_bits(cs42l42->regmap, CS42L42_PWR_CTL1, pdn_mask);
144		usleep_range(CS42L42_HP_ADC_EN_TIME_US, CS42L42_HP_ADC_EN_TIME_US + 1000);
145	} else if (state == SDW_OPS_PORT_POST_DEPREP) {
146		dev_dbg(cs42l42->dev, "Deprep Port pdn_mask:%x\n", pdn_mask);
147		regmap_set_bits(cs42l42->regmap, CS42L42_PWR_CTL1, pdn_mask);
148	}
149
150	return 0;
151}
152
153static int cs42l42_sdw_dai_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
154					  int direction)
155{
156	snd_soc_dai_dma_data_set(dai, direction, sdw_stream);
157
158	return 0;
159}
160
161static void cs42l42_sdw_dai_shutdown(struct snd_pcm_substream *substream,
162				     struct snd_soc_dai *dai)
163{
164	snd_soc_dai_set_dma_data(dai, substream, NULL);
165}
166
167static const struct snd_soc_dai_ops cs42l42_sdw_dai_ops = {
168	.startup	= cs42l42_sdw_dai_startup,
169	.shutdown	= cs42l42_sdw_dai_shutdown,
170	.hw_params	= cs42l42_sdw_dai_hw_params,
171	.prepare	= cs42l42_sdw_dai_prepare,
172	.hw_free	= cs42l42_sdw_dai_hw_free,
173	.mute_stream	= cs42l42_mute_stream,
174	.set_stream	= cs42l42_sdw_dai_set_sdw_stream,
175};
176
177static struct snd_soc_dai_driver cs42l42_sdw_dai = {
178	.name = "cs42l42-sdw",
179	.playback = {
180		.stream_name = "Playback",
181		.channels_min = 1,
182		.channels_max = 2,
183		/* Restrict which rates and formats are supported */
184		.rates = SNDRV_PCM_RATE_8000_96000,
185		.formats = SNDRV_PCM_FMTBIT_S16_LE |
186			   SNDRV_PCM_FMTBIT_S24_LE |
187			   SNDRV_PCM_FMTBIT_S32_LE,
188	},
189	.capture = {
190		.stream_name = "Capture",
191		.channels_min = 1,
192		.channels_max = 1,
193		/* Restrict which rates and formats are supported */
194		.rates = SNDRV_PCM_RATE_8000_96000,
195		.formats = SNDRV_PCM_FMTBIT_S16_LE |
196			   SNDRV_PCM_FMTBIT_S24_LE |
197			   SNDRV_PCM_FMTBIT_S32_LE,
198	},
199	.symmetric_rate = 1,
200	.ops = &cs42l42_sdw_dai_ops,
201};
202
203static int cs42l42_sdw_poll_status(struct sdw_slave *peripheral, u8 mask, u8 match)
204{
205	int ret, sdwret;
206
207	ret = read_poll_timeout(sdw_read_no_pm, sdwret,
208				(sdwret < 0) || ((sdwret & mask) == match),
209				CS42L42_DELAYED_READ_POLL_US, CS42L42_DELAYED_READ_TIMEOUT_US,
210				false, peripheral, CS42L42_SDW_MEM_ACCESS_STATUS);
211	if (ret == 0)
212		ret = sdwret;
213
214	if (ret < 0)
215		dev_err(&peripheral->dev, "MEM_ACCESS_STATUS & %#x for %#x fail: %d\n",
216			mask, match, ret);
217
218	return ret;
219}
220
221static int cs42l42_sdw_read(void *context, unsigned int reg, unsigned int *val)
222{
223	struct sdw_slave *peripheral = context;
224	u8 data;
225	int ret;
226
227	reg += CS42L42_SDW_ADDR_OFFSET;
228
229	ret = cs42l42_sdw_poll_status(peripheral, CS42L42_SDW_CMD_IN_PROGRESS, 0);
230	if (ret < 0)
231		return ret;
232
233	ret = sdw_read_no_pm(peripheral, reg);
234	if (ret < 0) {
235		dev_err(&peripheral->dev, "Failed to issue read @0x%x: %d\n", reg, ret);
236		return ret;
237	}
238
239	data = (u8)ret;	/* possible non-delayed read value */
240	ret = sdw_read_no_pm(peripheral, CS42L42_SDW_MEM_ACCESS_STATUS);
241	if (ret < 0) {
242		dev_err(&peripheral->dev, "Failed to read MEM_ACCESS_STATUS: %d\n", ret);
243		return ret;
244	}
245
246	/* If read was not delayed we already have the result */
247	if ((ret & CS42L42_SDW_LAST_LATE) == 0) {
248		*val = data;
249		return 0;
250	}
251
252	/* Poll for delayed read completion */
253	if ((ret & CS42L42_SDW_RDATA_RDY) == 0) {
254		ret = cs42l42_sdw_poll_status(peripheral,
255					      CS42L42_SDW_RDATA_RDY, CS42L42_SDW_RDATA_RDY);
256		if (ret < 0)
257			return ret;
258	}
259
260	ret = sdw_read_no_pm(peripheral, CS42L42_SDW_MEM_READ_DATA);
261	if (ret < 0) {
262		dev_err(&peripheral->dev, "Failed to read READ_DATA: %d\n", ret);
263		return ret;
264	}
265
266	*val = (u8)ret;
267
268	return 0;
269}
270
271static int cs42l42_sdw_write(void *context, unsigned int reg, unsigned int val)
272{
273	struct sdw_slave *peripheral = context;
274	int ret;
275
276	ret = cs42l42_sdw_poll_status(peripheral, CS42L42_SDW_CMD_IN_PROGRESS, 0);
277	if (ret < 0)
278		return ret;
279
280	return sdw_write_no_pm(peripheral, reg + CS42L42_SDW_ADDR_OFFSET, (u8)val);
281}
282
283/* Initialise cs42l42 using SoundWire - this is only called once, during initialisation */
284static void cs42l42_sdw_init(struct sdw_slave *peripheral)
285{
286	struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev);
287	int ret;
288
289	regcache_cache_only(cs42l42->regmap, false);
290
291	ret = cs42l42_init(cs42l42);
292	if (ret < 0) {
293		regcache_cache_only(cs42l42->regmap, true);
294		goto err;
295	}
296
297	/* Write out any cached changes that happened between probe and attach */
298	ret = regcache_sync(cs42l42->regmap);
299	if (ret < 0)
300		dev_warn(cs42l42->dev, "Failed to sync cache: %d\n", ret);
301
302	/* Disable internal logic that makes clock-stop conditional */
303	regmap_clear_bits(cs42l42->regmap, CS42L42_PWR_CTL3, CS42L42_SW_CLK_STP_STAT_SEL_MASK);
304
305err:
306	/* This cancels the pm_runtime_get_noresume() call from cs42l42_sdw_probe(). */
307	pm_runtime_put_autosuspend(cs42l42->dev);
308}
309
310static int cs42l42_sdw_read_prop(struct sdw_slave *peripheral)
311{
312	struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev);
313	struct sdw_slave_prop *prop = &peripheral->prop;
314	struct sdw_dpn_prop *ports;
315
316	ports = devm_kcalloc(cs42l42->dev, 2, sizeof(*ports), GFP_KERNEL);
317	if (!ports)
318		return -ENOMEM;
319
320	prop->source_ports = BIT(CS42L42_SDW_CAPTURE_PORT);
321	prop->sink_ports = BIT(CS42L42_SDW_PLAYBACK_PORT);
322	prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY;
323	prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY;
324
325	/* DP1 - capture */
326	ports[0].num = CS42L42_SDW_CAPTURE_PORT;
327	ports[0].type = SDW_DPN_FULL;
328	ports[0].ch_prep_timeout = 10;
329	prop->src_dpn_prop = &ports[0];
330
331	/* DP2 - playback */
332	ports[1].num = CS42L42_SDW_PLAYBACK_PORT;
333	ports[1].type = SDW_DPN_FULL;
334	ports[1].ch_prep_timeout = 10;
335	prop->sink_dpn_prop = &ports[1];
336
337	return 0;
338}
339
340static int cs42l42_sdw_update_status(struct sdw_slave *peripheral,
341				     enum sdw_slave_status status)
342{
343	struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev);
344
345	switch (status) {
346	case SDW_SLAVE_ATTACHED:
347		dev_dbg(cs42l42->dev, "ATTACHED\n");
348
349		/*
350		 * The SoundWire core can report stale ATTACH notifications
351		 * if we hard-reset CS42L42 in probe() but it had already been
352		 * enumerated. Reject the ATTACH if we haven't yet seen an
353		 * UNATTACH report for the device being in reset.
354		 */
355		if (cs42l42->sdw_waiting_first_unattach)
356			break;
357
358		/*
359		 * Initialise codec, this only needs to be done once.
360		 * When resuming from suspend, resume callback will handle re-init of codec,
361		 * using regcache_sync().
362		 */
363		if (!cs42l42->init_done)
364			cs42l42_sdw_init(peripheral);
365		break;
366	case SDW_SLAVE_UNATTACHED:
367		dev_dbg(cs42l42->dev, "UNATTACHED\n");
368
369		if (cs42l42->sdw_waiting_first_unattach) {
370			/*
371			 * SoundWire core has seen that CS42L42 is not on
372			 * the bus so release RESET and wait for ATTACH.
373			 */
374			cs42l42->sdw_waiting_first_unattach = false;
375			gpiod_set_value_cansleep(cs42l42->reset_gpio, 1);
376		}
377
378		break;
379	default:
380		break;
381	}
382
383	return 0;
384}
385
386static int cs42l42_sdw_bus_config(struct sdw_slave *peripheral,
387				  struct sdw_bus_params *params)
388{
389	struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev);
390	unsigned int new_sclk = params->curr_dr_freq / 2;
391
392	/* The cs42l42 cannot support a glitchless SWIRE_CLK change. */
393	if ((new_sclk != cs42l42->sclk) && cs42l42->stream_use) {
394		dev_warn(cs42l42->dev, "Rejected SCLK change while audio active\n");
395		return -EBUSY;
396	}
397
398	cs42l42->sclk = new_sclk;
399
400	dev_dbg(cs42l42->dev, "bus_config: sclk=%u c=%u r=%u\n",
401		cs42l42->sclk, params->col, params->row);
402
403	return 0;
404}
405
406static const struct sdw_slave_ops cs42l42_sdw_ops = {
407/* No interrupt callback because only hardware INT is supported for Jack Detect in the CS42L42 */
408	.read_prop = cs42l42_sdw_read_prop,
409	.update_status = cs42l42_sdw_update_status,
410	.bus_config = cs42l42_sdw_bus_config,
411	.port_prep = cs42l42_sdw_port_prep,
412};
413
414static int __maybe_unused cs42l42_sdw_runtime_suspend(struct device *dev)
415{
416	struct cs42l42_private *cs42l42 = dev_get_drvdata(dev);
417
418	dev_dbg(dev, "Runtime suspend\n");
419
420	if (!cs42l42->init_done)
421		return 0;
422
423	/* The host controller could suspend, which would mean no register access */
424	regcache_cache_only(cs42l42->regmap, true);
425
426	return 0;
427}
428
429static const struct reg_sequence __maybe_unused cs42l42_soft_reboot_seq[] = {
430	REG_SEQ0(CS42L42_SOFT_RESET_REBOOT, 0x1e),
431};
432
433static int __maybe_unused cs42l42_sdw_handle_unattach(struct cs42l42_private *cs42l42)
434{
435	struct sdw_slave *peripheral = cs42l42->sdw_peripheral;
436
437	if (!peripheral->unattach_request)
438		return 0;
439
440	/* Cannot access registers until master re-attaches. */
441	dev_dbg(&peripheral->dev, "Wait for initialization_complete\n");
442	if (!wait_for_completion_timeout(&peripheral->initialization_complete,
443					 msecs_to_jiffies(5000))) {
444		dev_err(&peripheral->dev, "initialization_complete timed out\n");
445		return -ETIMEDOUT;
446	}
447
448	peripheral->unattach_request = 0;
449
450	/*
451	 * After a bus reset there must be a reconfiguration reset to
452	 * reinitialize the internal state of CS42L42.
453	 */
454	regmap_multi_reg_write_bypassed(cs42l42->regmap,
455					cs42l42_soft_reboot_seq,
456					ARRAY_SIZE(cs42l42_soft_reboot_seq));
457	usleep_range(CS42L42_BOOT_TIME_US, CS42L42_BOOT_TIME_US * 2);
458	regcache_mark_dirty(cs42l42->regmap);
459
460	return 0;
461}
462
463static int __maybe_unused cs42l42_sdw_runtime_resume(struct device *dev)
464{
465	static const unsigned int ts_dbnce_ms[] = { 0, 125, 250, 500, 750, 1000, 1250, 1500};
466	struct cs42l42_private *cs42l42 = dev_get_drvdata(dev);
467	unsigned int dbnce;
468	int ret;
469
470	dev_dbg(dev, "Runtime resume\n");
471
472	if (!cs42l42->init_done)
473		return 0;
474
475	ret = cs42l42_sdw_handle_unattach(cs42l42);
476	if (ret < 0) {
477		return ret;
478	} else if (ret > 0) {
479		dbnce = max(cs42l42->ts_dbnc_rise, cs42l42->ts_dbnc_fall);
480
481		if (dbnce > 0)
482			msleep(ts_dbnce_ms[dbnce]);
483	}
484
485	regcache_cache_only(cs42l42->regmap, false);
486
487	/* Sync LATCH_TO_VP first so the VP domain registers sync correctly */
488	regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1);
489	regcache_sync(cs42l42->regmap);
490
491	return 0;
492}
493
494static int __maybe_unused cs42l42_sdw_resume(struct device *dev)
495{
496	struct cs42l42_private *cs42l42 = dev_get_drvdata(dev);
497	int ret;
498
499	dev_dbg(dev, "System resume\n");
500
501	/* Power-up so it can re-enumerate */
502	ret = cs42l42_resume(dev);
503	if (ret)
504		return ret;
505
506	/* Wait for re-attach */
507	ret = cs42l42_sdw_handle_unattach(cs42l42);
508	if (ret < 0)
509		return ret;
510
511	cs42l42_resume_restore(dev);
512
513	return 0;
514}
515
516static int cs42l42_sdw_probe(struct sdw_slave *peripheral, const struct sdw_device_id *id)
517{
518	struct snd_soc_component_driver *component_drv;
519	struct device *dev = &peripheral->dev;
520	struct cs42l42_private *cs42l42;
521	struct regmap_config *regmap_conf;
522	struct regmap *regmap;
523	int irq, ret;
524
525	cs42l42 = devm_kzalloc(dev, sizeof(*cs42l42), GFP_KERNEL);
526	if (!cs42l42)
527		return -ENOMEM;
528
529	if (has_acpi_companion(dev))
530		irq = acpi_dev_gpio_irq_get(ACPI_COMPANION(dev), 0);
531	else
532		irq = of_irq_get(dev->of_node, 0);
533
534	if (irq == -ENOENT)
535		irq = 0;
536	else if (irq < 0)
537		return dev_err_probe(dev, irq, "Failed to get IRQ\n");
538
539	regmap_conf = devm_kmemdup(dev, &cs42l42_regmap, sizeof(cs42l42_regmap), GFP_KERNEL);
540	if (!regmap_conf)
541		return -ENOMEM;
542	regmap_conf->reg_bits = 16;
543	regmap_conf->num_ranges = 0;
544	regmap_conf->reg_read = cs42l42_sdw_read;
545	regmap_conf->reg_write = cs42l42_sdw_write;
546
547	regmap = devm_regmap_init(dev, NULL, peripheral, regmap_conf);
548	if (IS_ERR(regmap))
549		return dev_err_probe(dev, PTR_ERR(regmap), "Failed to allocate register map\n");
550
551	/* Start in cache-only until device is enumerated */
552	regcache_cache_only(regmap, true);
553
554	component_drv = devm_kmemdup(dev,
555				     &cs42l42_soc_component,
556				     sizeof(cs42l42_soc_component),
557				     GFP_KERNEL);
558	if (!component_drv)
559		return -ENOMEM;
560
561	component_drv->dapm_routes = cs42l42_sdw_audio_map;
562	component_drv->num_dapm_routes = ARRAY_SIZE(cs42l42_sdw_audio_map);
563
564	cs42l42->dev = dev;
565	cs42l42->regmap = regmap;
566	cs42l42->sdw_peripheral = peripheral;
567	cs42l42->irq = irq;
568	cs42l42->devid = CS42L42_CHIP_ID;
569
570	/*
571	 * pm_runtime is needed to control bus manager suspend, and to
572	 * recover from an unattach_request when the manager suspends.
573	 */
574	pm_runtime_set_autosuspend_delay(cs42l42->dev, 3000);
575	pm_runtime_use_autosuspend(cs42l42->dev);
576	pm_runtime_mark_last_busy(cs42l42->dev);
577	pm_runtime_set_active(cs42l42->dev);
578	pm_runtime_get_noresume(cs42l42->dev);
579	pm_runtime_enable(cs42l42->dev);
580
581	ret = cs42l42_common_probe(cs42l42, component_drv, &cs42l42_sdw_dai);
582	if (ret < 0)
583		return ret;
584
585	return 0;
586}
587
588static int cs42l42_sdw_remove(struct sdw_slave *peripheral)
589{
590	struct cs42l42_private *cs42l42 = dev_get_drvdata(&peripheral->dev);
591
592	cs42l42_common_remove(cs42l42);
593	pm_runtime_disable(cs42l42->dev);
594
595	return 0;
596}
597
598static const struct dev_pm_ops cs42l42_sdw_pm = {
599	SET_SYSTEM_SLEEP_PM_OPS(cs42l42_suspend, cs42l42_sdw_resume)
600	SET_RUNTIME_PM_OPS(cs42l42_sdw_runtime_suspend, cs42l42_sdw_runtime_resume, NULL)
601};
602
603static const struct sdw_device_id cs42l42_sdw_id[] = {
604	SDW_SLAVE_ENTRY(0x01FA, 0x4242, 0),
605	{},
606};
607MODULE_DEVICE_TABLE(sdw, cs42l42_sdw_id);
608
609static struct sdw_driver cs42l42_sdw_driver = {
610	.driver = {
611		.name = "cs42l42-sdw",
612		.pm = &cs42l42_sdw_pm,
613	},
614	.probe = cs42l42_sdw_probe,
615	.remove = cs42l42_sdw_remove,
616	.ops = &cs42l42_sdw_ops,
617	.id_table = cs42l42_sdw_id,
618};
619
620module_sdw_driver(cs42l42_sdw_driver);
621
622MODULE_DESCRIPTION("ASoC CS42L42 SoundWire driver");
623MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
624MODULE_LICENSE("GPL");
625MODULE_IMPORT_NS("SND_SOC_CS42L42_CORE");