Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/sound/hda/codecs/side-codecs/cs35l56_hda.c
51323 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
//
3
// HDA audio driver for Cirrus Logic CS35L56 smart amp
4
//
5
// Copyright (C) 2023 Cirrus Logic, Inc. and
6
// Cirrus Logic International Semiconductor Ltd.
7
//
8
9
#include <linux/acpi.h>
10
#include <linux/debugfs.h>
11
#include <linux/gpio/consumer.h>
12
#include <linux/module.h>
13
#include <linux/pm_runtime.h>
14
#include <linux/regmap.h>
15
#include <linux/slab.h>
16
#include <sound/core.h>
17
#include <sound/cs-amp-lib.h>
18
#include <sound/hda_codec.h>
19
#include <sound/tlv.h>
20
#include "cirrus_scodec.h"
21
#include "cs35l56_hda.h"
22
#include "hda_component.h"
23
#include "../generic.h"
24
25
/*
26
* The cs35l56_hda_dai_config[] reg sequence configures the device as
27
* ASP1_BCLK_FREQ = 3.072 MHz
28
* ASP1_RX_WIDTH = 32 cycles per slot, ASP1_TX_WIDTH = 32 cycles per slot, ASP1_FMT = I2S
29
* ASP1_DOUT_HIZ_CONTROL = Hi-Z during unused timeslots
30
* ASP1_RX_WL = 24 bits per sample
31
* ASP1_TX_WL = 24 bits per sample
32
* ASP1_RXn_EN 1..3 and ASP1_TXn_EN 1..4 disabled
33
*
34
* Override any Windows-specific mixer settings applied by the firmware.
35
*/
36
static const struct reg_sequence cs35l56_hda_dai_config[] = {
37
{ CS35L56_ASP1_CONTROL1, 0x00000021 },
38
{ CS35L56_ASP1_CONTROL2, 0x20200200 },
39
{ CS35L56_ASP1_CONTROL3, 0x00000003 },
40
{ CS35L56_ASP1_FRAME_CONTROL1, 0x03020100 },
41
{ CS35L56_ASP1_FRAME_CONTROL5, 0x00020100 },
42
{ CS35L56_ASP1_DATA_CONTROL5, 0x00000018 },
43
{ CS35L56_ASP1_DATA_CONTROL1, 0x00000018 },
44
{ CS35L56_ASP1_ENABLES1, 0x00000000 },
45
{ CS35L56_ASP1TX1_INPUT, 0x00000018 },
46
{ CS35L56_ASP1TX2_INPUT, 0x00000019 },
47
{ CS35L56_ASP1TX3_INPUT, 0x00000020 },
48
{ CS35L56_ASP1TX4_INPUT, 0x00000028 },
49
50
};
51
52
static void cs35l56_hda_wait_dsp_ready(struct cs35l56_hda *cs35l56)
53
{
54
/* Wait for patching to complete */
55
flush_work(&cs35l56->dsp_work);
56
}
57
58
static void cs35l56_hda_play(struct cs35l56_hda *cs35l56)
59
{
60
unsigned int val;
61
int ret;
62
63
cs35l56_hda_wait_dsp_ready(cs35l56);
64
65
pm_runtime_get_sync(cs35l56->base.dev);
66
ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_PLAY);
67
if (ret == 0) {
68
/* Wait for firmware to enter PS0 power state */
69
ret = regmap_read_poll_timeout(cs35l56->base.regmap,
70
cs35l56->base.fw_reg->transducer_actual_ps,
71
val, (val == CS35L56_PS0),
72
CS35L56_PS0_POLL_US,
73
CS35L56_PS0_TIMEOUT_US);
74
if (ret)
75
dev_warn(cs35l56->base.dev, "PS0 wait failed: %d\n", ret);
76
}
77
regmap_set_bits(cs35l56->base.regmap, CS35L56_ASP1_ENABLES1,
78
BIT(CS35L56_ASP_RX1_EN_SHIFT) | BIT(CS35L56_ASP_RX2_EN_SHIFT) |
79
cs35l56->asp_tx_mask);
80
cs35l56->playing = true;
81
}
82
83
static void cs35l56_hda_pause(struct cs35l56_hda *cs35l56)
84
{
85
cs35l56->playing = false;
86
cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_PAUSE);
87
regmap_clear_bits(cs35l56->base.regmap, CS35L56_ASP1_ENABLES1,
88
BIT(CS35L56_ASP_RX1_EN_SHIFT) | BIT(CS35L56_ASP_RX2_EN_SHIFT) |
89
BIT(CS35L56_ASP_TX1_EN_SHIFT) | BIT(CS35L56_ASP_TX2_EN_SHIFT) |
90
BIT(CS35L56_ASP_TX3_EN_SHIFT) | BIT(CS35L56_ASP_TX4_EN_SHIFT));
91
92
pm_runtime_put_autosuspend(cs35l56->base.dev);
93
}
94
95
static void cs35l56_hda_playback_hook(struct device *dev, int action)
96
{
97
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
98
99
dev_dbg(cs35l56->base.dev, "%s()%d: action: %d\n", __func__, __LINE__, action);
100
101
switch (action) {
102
case HDA_GEN_PCM_ACT_PREPARE:
103
if (cs35l56->playing)
104
break;
105
106
/* If we're suspended: flag that resume should start playback */
107
if (cs35l56->suspended) {
108
cs35l56->playing = true;
109
break;
110
}
111
112
cs35l56_hda_play(cs35l56);
113
break;
114
case HDA_GEN_PCM_ACT_CLEANUP:
115
if (!cs35l56->playing)
116
break;
117
118
cs35l56_hda_pause(cs35l56);
119
break;
120
default:
121
break;
122
}
123
}
124
125
static int cs35l56_hda_runtime_suspend(struct device *dev)
126
{
127
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
128
129
if (cs35l56->cs_dsp.booted)
130
cs_dsp_stop(&cs35l56->cs_dsp);
131
132
return cs35l56_runtime_suspend_common(&cs35l56->base);
133
}
134
135
static int cs35l56_hda_runtime_resume(struct device *dev)
136
{
137
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
138
int ret;
139
140
ret = cs35l56_runtime_resume_common(&cs35l56->base, false);
141
if (ret < 0)
142
return ret;
143
144
if (cs35l56->cs_dsp.booted) {
145
ret = cs_dsp_run(&cs35l56->cs_dsp);
146
if (ret) {
147
dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret);
148
goto err;
149
}
150
}
151
152
return 0;
153
154
err:
155
cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE);
156
regmap_write(cs35l56->base.regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
157
CS35L56_MBOX_CMD_HIBERNATE_NOW);
158
159
regcache_cache_only(cs35l56->base.regmap, true);
160
161
return ret;
162
}
163
164
static int cs35l56_hda_mixer_info(struct snd_kcontrol *kcontrol,
165
struct snd_ctl_elem_info *uinfo)
166
{
167
uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
168
uinfo->count = 1;
169
uinfo->value.enumerated.items = CS35L56_NUM_INPUT_SRC;
170
if (uinfo->value.enumerated.item >= CS35L56_NUM_INPUT_SRC)
171
uinfo->value.enumerated.item = CS35L56_NUM_INPUT_SRC - 1;
172
strscpy(uinfo->value.enumerated.name, cs35l56_tx_input_texts[uinfo->value.enumerated.item],
173
sizeof(uinfo->value.enumerated.name));
174
175
return 0;
176
}
177
178
static int cs35l56_hda_mixer_get(struct snd_kcontrol *kcontrol,
179
struct snd_ctl_elem_value *ucontrol)
180
{
181
struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol);
182
unsigned int reg_val;
183
int i;
184
185
cs35l56_hda_wait_dsp_ready(cs35l56);
186
187
regmap_read(cs35l56->base.regmap, kcontrol->private_value, &reg_val);
188
reg_val &= CS35L56_ASP_TXn_SRC_MASK;
189
190
for (i = 0; i < CS35L56_NUM_INPUT_SRC; ++i) {
191
if (cs35l56_tx_input_values[i] == reg_val) {
192
ucontrol->value.enumerated.item[0] = i;
193
break;
194
}
195
}
196
197
return 0;
198
}
199
200
static int cs35l56_hda_mixer_put(struct snd_kcontrol *kcontrol,
201
struct snd_ctl_elem_value *ucontrol)
202
{
203
struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol);
204
unsigned int item = ucontrol->value.enumerated.item[0];
205
bool changed;
206
207
if (item >= CS35L56_NUM_INPUT_SRC)
208
return -EINVAL;
209
210
cs35l56_hda_wait_dsp_ready(cs35l56);
211
212
regmap_update_bits_check(cs35l56->base.regmap, kcontrol->private_value,
213
CS35L56_INPUT_MASK, cs35l56_tx_input_values[item],
214
&changed);
215
216
return changed;
217
}
218
219
static int cs35l56_hda_posture_info(struct snd_kcontrol *kcontrol,
220
struct snd_ctl_elem_info *uinfo)
221
{
222
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
223
uinfo->count = 1;
224
uinfo->value.integer.min = CS35L56_MAIN_POSTURE_MIN;
225
uinfo->value.integer.max = CS35L56_MAIN_POSTURE_MAX;
226
return 0;
227
}
228
229
static int cs35l56_hda_posture_get(struct snd_kcontrol *kcontrol,
230
struct snd_ctl_elem_value *ucontrol)
231
{
232
struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol);
233
unsigned int pos;
234
int ret;
235
236
cs35l56_hda_wait_dsp_ready(cs35l56);
237
238
ret = regmap_read(cs35l56->base.regmap,
239
cs35l56->base.fw_reg->posture_number, &pos);
240
if (ret)
241
return ret;
242
243
ucontrol->value.integer.value[0] = pos;
244
245
return 0;
246
}
247
248
static int cs35l56_hda_posture_put(struct snd_kcontrol *kcontrol,
249
struct snd_ctl_elem_value *ucontrol)
250
{
251
struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol);
252
unsigned long pos = ucontrol->value.integer.value[0];
253
bool changed;
254
int ret;
255
256
if ((pos < CS35L56_MAIN_POSTURE_MIN) ||
257
(pos > CS35L56_MAIN_POSTURE_MAX))
258
return -EINVAL;
259
260
cs35l56_hda_wait_dsp_ready(cs35l56);
261
262
ret = regmap_update_bits_check(cs35l56->base.regmap, cs35l56->base.fw_reg->posture_number,
263
CS35L56_MAIN_POSTURE_MASK, pos, &changed);
264
if (ret)
265
return ret;
266
267
return changed;
268
}
269
270
static const struct {
271
const char *name;
272
unsigned int reg;
273
} cs35l56_hda_mixer_controls[] = {
274
{ "ASP1 TX1 Source", CS35L56_ASP1TX1_INPUT },
275
{ "ASP1 TX2 Source", CS35L56_ASP1TX2_INPUT },
276
{ "ASP1 TX3 Source", CS35L56_ASP1TX3_INPUT },
277
{ "ASP1 TX4 Source", CS35L56_ASP1TX4_INPUT },
278
};
279
280
static const DECLARE_TLV_DB_SCALE(cs35l56_hda_vol_tlv, -10000, 25, 0);
281
282
static int cs35l56_hda_vol_info(struct snd_kcontrol *kcontrol,
283
struct snd_ctl_elem_info *uinfo)
284
{
285
uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
286
uinfo->count = 1;
287
uinfo->value.integer.step = 1;
288
uinfo->value.integer.min = 0;
289
uinfo->value.integer.max = CS35L56_MAIN_RENDER_USER_VOLUME_MAX -
290
CS35L56_MAIN_RENDER_USER_VOLUME_MIN;
291
292
return 0;
293
}
294
295
static int cs35l56_hda_vol_get(struct snd_kcontrol *kcontrol,
296
struct snd_ctl_elem_value *ucontrol)
297
{
298
struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol);
299
unsigned int raw_vol;
300
int vol;
301
int ret;
302
303
cs35l56_hda_wait_dsp_ready(cs35l56);
304
305
ret = regmap_read(cs35l56->base.regmap, cs35l56->base.fw_reg->user_volume, &raw_vol);
306
307
if (ret)
308
return ret;
309
310
vol = (s16)(raw_vol & 0xFFFF);
311
vol >>= CS35L56_MAIN_RENDER_USER_VOLUME_SHIFT;
312
313
if (vol & BIT(CS35L56_MAIN_RENDER_USER_VOLUME_SIGNBIT))
314
vol |= ~((int)(BIT(CS35L56_MAIN_RENDER_USER_VOLUME_SIGNBIT) - 1));
315
316
ucontrol->value.integer.value[0] = vol - CS35L56_MAIN_RENDER_USER_VOLUME_MIN;
317
318
return 0;
319
}
320
321
static int cs35l56_hda_vol_put(struct snd_kcontrol *kcontrol,
322
struct snd_ctl_elem_value *ucontrol)
323
{
324
struct cs35l56_hda *cs35l56 = snd_kcontrol_chip(kcontrol);
325
long vol = ucontrol->value.integer.value[0];
326
unsigned int raw_vol;
327
bool changed;
328
int ret;
329
330
if ((vol < 0) || (vol > (CS35L56_MAIN_RENDER_USER_VOLUME_MAX -
331
CS35L56_MAIN_RENDER_USER_VOLUME_MIN)))
332
return -EINVAL;
333
334
raw_vol = (vol + CS35L56_MAIN_RENDER_USER_VOLUME_MIN) <<
335
CS35L56_MAIN_RENDER_USER_VOLUME_SHIFT;
336
337
cs35l56_hda_wait_dsp_ready(cs35l56);
338
339
ret = regmap_update_bits_check(cs35l56->base.regmap, cs35l56->base.fw_reg->user_volume,
340
CS35L56_MAIN_RENDER_USER_VOLUME_MASK, raw_vol, &changed);
341
if (ret)
342
return ret;
343
344
return changed;
345
}
346
347
static void cs35l56_hda_create_controls(struct cs35l56_hda *cs35l56)
348
{
349
struct snd_kcontrol_new ctl_template = {
350
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
351
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
352
.info = cs35l56_hda_posture_info,
353
.get = cs35l56_hda_posture_get,
354
.put = cs35l56_hda_posture_put,
355
};
356
char name[64];
357
int i;
358
359
snprintf(name, sizeof(name), "%s Posture Number", cs35l56->amp_name);
360
ctl_template.name = name;
361
cs35l56->posture_ctl = snd_ctl_new1(&ctl_template, cs35l56);
362
if (snd_ctl_add(cs35l56->codec->card, cs35l56->posture_ctl))
363
dev_err(cs35l56->base.dev, "Failed to add KControl: %s\n", ctl_template.name);
364
365
/* Mixer controls */
366
ctl_template.info = cs35l56_hda_mixer_info;
367
ctl_template.get = cs35l56_hda_mixer_get;
368
ctl_template.put = cs35l56_hda_mixer_put;
369
370
BUILD_BUG_ON(ARRAY_SIZE(cs35l56->mixer_ctl) != ARRAY_SIZE(cs35l56_hda_mixer_controls));
371
372
for (i = 0; i < ARRAY_SIZE(cs35l56_hda_mixer_controls); ++i) {
373
snprintf(name, sizeof(name), "%s %s", cs35l56->amp_name,
374
cs35l56_hda_mixer_controls[i].name);
375
ctl_template.private_value = cs35l56_hda_mixer_controls[i].reg;
376
cs35l56->mixer_ctl[i] = snd_ctl_new1(&ctl_template, cs35l56);
377
if (snd_ctl_add(cs35l56->codec->card, cs35l56->mixer_ctl[i])) {
378
dev_err(cs35l56->base.dev, "Failed to add KControl: %s\n",
379
ctl_template.name);
380
}
381
}
382
383
ctl_template.info = cs35l56_hda_vol_info;
384
ctl_template.get = cs35l56_hda_vol_get;
385
ctl_template.put = cs35l56_hda_vol_put;
386
ctl_template.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ);
387
ctl_template.tlv.p = cs35l56_hda_vol_tlv;
388
snprintf(name, sizeof(name), "%s Speaker Playback Volume", cs35l56->amp_name);
389
ctl_template.name = name;
390
cs35l56->volume_ctl = snd_ctl_new1(&ctl_template, cs35l56);
391
if (snd_ctl_add(cs35l56->codec->card, cs35l56->volume_ctl))
392
dev_err(cs35l56->base.dev, "Failed to add KControl: %s\n", ctl_template.name);
393
}
394
395
static void cs35l56_hda_remove_controls(struct cs35l56_hda *cs35l56)
396
{
397
int i;
398
399
for (i = ARRAY_SIZE(cs35l56->mixer_ctl) - 1; i >= 0; i--)
400
snd_ctl_remove(cs35l56->codec->card, cs35l56->mixer_ctl[i]);
401
402
snd_ctl_remove(cs35l56->codec->card, cs35l56->posture_ctl);
403
snd_ctl_remove(cs35l56->codec->card, cs35l56->volume_ctl);
404
}
405
406
static const struct cs_dsp_client_ops cs35l56_hda_client_ops = {
407
/* cs_dsp requires the client to provide this even if it is empty */
408
};
409
410
static int cs35l56_hda_request_firmware_file(struct cs35l56_hda *cs35l56,
411
const struct firmware **firmware, char **filename,
412
const char *base_name, const char *system_name,
413
const char *amp_name,
414
const char *filetype)
415
{
416
char *s, c;
417
int ret = 0;
418
419
if (system_name && amp_name)
420
*filename = kasprintf(GFP_KERNEL, "%s-%s-%s.%s", base_name,
421
system_name, amp_name, filetype);
422
else if (system_name)
423
*filename = kasprintf(GFP_KERNEL, "%s-%s.%s", base_name,
424
system_name, filetype);
425
else
426
*filename = kasprintf(GFP_KERNEL, "%s.%s", base_name, filetype);
427
428
if (!*filename)
429
return -ENOMEM;
430
431
/*
432
* Make sure that filename is lower-case and any non alpha-numeric
433
* characters except full stop and forward slash are replaced with
434
* hyphens.
435
*/
436
s = *filename;
437
while (*s) {
438
c = *s;
439
if (isalnum(c))
440
*s = tolower(c);
441
else if (c != '.' && c != '/')
442
*s = '-';
443
s++;
444
}
445
446
ret = firmware_request_nowarn(firmware, *filename, cs35l56->base.dev);
447
if (ret) {
448
dev_dbg(cs35l56->base.dev, "Failed to request '%s'\n", *filename);
449
kfree(*filename);
450
*filename = NULL;
451
return ret;
452
}
453
454
dev_dbg(cs35l56->base.dev, "Found '%s'\n", *filename);
455
456
return 0;
457
}
458
459
static void cs35l56_hda_request_firmware_files(struct cs35l56_hda *cs35l56,
460
unsigned int preloaded_fw_ver,
461
const struct firmware **wmfw_firmware,
462
char **wmfw_filename,
463
const struct firmware **coeff_firmware,
464
char **coeff_filename)
465
{
466
const char *system_name = cs35l56->system_name;
467
const char *amp_name = cs35l56->amp_name;
468
char base_name[37];
469
int ret;
470
471
if (preloaded_fw_ver) {
472
snprintf(base_name, sizeof(base_name),
473
"cirrus/cs35l%02x-%02x%s-%06x-dsp1-misc",
474
cs35l56->base.type,
475
cs35l56->base.rev,
476
cs35l56->base.secured ? "-s" : "",
477
preloaded_fw_ver & 0xffffff);
478
} else {
479
snprintf(base_name, sizeof(base_name),
480
"cirrus/cs35l%02x-%02x%s-dsp1-misc",
481
cs35l56->base.type,
482
cs35l56->base.rev,
483
cs35l56->base.secured ? "-s" : "");
484
}
485
486
if (system_name && amp_name) {
487
if (!cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,
488
base_name, system_name, amp_name, "wmfw")) {
489
cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
490
base_name, system_name, amp_name, "bin");
491
return;
492
}
493
}
494
495
if (system_name) {
496
if (!cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,
497
base_name, system_name, NULL, "wmfw")) {
498
if (amp_name)
499
cs35l56_hda_request_firmware_file(cs35l56,
500
coeff_firmware, coeff_filename,
501
base_name, system_name,
502
amp_name, "bin");
503
if (!*coeff_firmware)
504
cs35l56_hda_request_firmware_file(cs35l56,
505
coeff_firmware, coeff_filename,
506
base_name, system_name,
507
NULL, "bin");
508
return;
509
}
510
511
/*
512
* Check for system-specific bin files without wmfw before
513
* falling back to generic firmware
514
*/
515
if (amp_name)
516
cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
517
base_name, system_name, amp_name, "bin");
518
if (!*coeff_firmware)
519
cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
520
base_name, system_name, NULL, "bin");
521
522
if (*coeff_firmware)
523
return;
524
}
525
526
ret = cs35l56_hda_request_firmware_file(cs35l56, wmfw_firmware, wmfw_filename,
527
base_name, NULL, NULL, "wmfw");
528
if (!ret) {
529
cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
530
base_name, NULL, NULL, "bin");
531
return;
532
}
533
534
if (!*coeff_firmware)
535
cs35l56_hda_request_firmware_file(cs35l56, coeff_firmware, coeff_filename,
536
base_name, NULL, NULL, "bin");
537
}
538
539
static void cs35l56_hda_release_firmware_files(const struct firmware *wmfw_firmware,
540
char *wmfw_filename,
541
const struct firmware *coeff_firmware,
542
char *coeff_filename)
543
{
544
release_firmware(wmfw_firmware);
545
kfree(wmfw_filename);
546
547
release_firmware(coeff_firmware);
548
kfree(coeff_filename);
549
}
550
551
static int cs35l56_hda_apply_calibration(struct cs35l56_hda *cs35l56)
552
{
553
int ret;
554
555
if (!cs35l56->base.cal_data_valid || cs35l56->base.secured)
556
return -EACCES;
557
558
ret = cs_amp_write_cal_coeffs(&cs35l56->cs_dsp,
559
&cs35l56_calibration_controls,
560
&cs35l56->base.cal_data);
561
if (ret < 0) {
562
dev_warn(cs35l56->base.dev, "Failed to write calibration: %d\n", ret);
563
return ret;
564
}
565
566
dev_info(cs35l56->base.dev, "Calibration applied\n");
567
568
return 0;
569
}
570
571
static void cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
572
{
573
const struct firmware *coeff_firmware = NULL;
574
const struct firmware *wmfw_firmware = NULL;
575
char *coeff_filename = NULL;
576
char *wmfw_filename = NULL;
577
unsigned int preloaded_fw_ver;
578
bool firmware_missing;
579
int ret;
580
581
/*
582
* Prepare for a new DSP power-up. If the DSP has had firmware
583
* downloaded previously then it needs to be powered down so that it
584
* can be updated.
585
*/
586
if (cs35l56->base.fw_patched)
587
cs_dsp_power_down(&cs35l56->cs_dsp);
588
589
cs35l56->base.fw_patched = false;
590
591
PM_RUNTIME_ACQUIRE_IF_ENABLED(cs35l56->base.dev, pm);
592
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
593
if (ret < 0) {
594
dev_err(cs35l56->base.dev, "Failed to resume and get %d\n", ret);
595
return;
596
}
597
598
/*
599
* The firmware can only be upgraded if it is currently running
600
* from the built-in ROM. If not, the wmfw/bin must be for the
601
* version of firmware that is running on the chip.
602
*/
603
ret = cs35l56_read_prot_status(&cs35l56->base, &firmware_missing, &preloaded_fw_ver);
604
if (ret)
605
return;
606
607
if (firmware_missing)
608
preloaded_fw_ver = 0;
609
610
cs35l56_hda_request_firmware_files(cs35l56, preloaded_fw_ver,
611
&wmfw_firmware, &wmfw_filename,
612
&coeff_firmware, &coeff_filename);
613
614
/*
615
* If the BIOS didn't patch the firmware a bin file is mandatory to
616
* enable the ASPĀ·
617
*/
618
if (!coeff_firmware && firmware_missing) {
619
dev_err(cs35l56->base.dev, ".bin file required but not found\n");
620
goto err_fw_release;
621
}
622
623
mutex_lock(&cs35l56->base.irq_lock);
624
625
/*
626
* If the firmware hasn't been patched it must be shutdown before
627
* doing a full patch and reset afterwards. If it is already
628
* running a patched version the firmware files only contain
629
* tunings and we can use the lower cost reinit sequence instead.
630
*/
631
if (firmware_missing && (wmfw_firmware || coeff_firmware)) {
632
ret = cs35l56_firmware_shutdown(&cs35l56->base);
633
if (ret)
634
goto err;
635
}
636
637
ret = cs_dsp_power_up(&cs35l56->cs_dsp, wmfw_firmware, wmfw_filename,
638
coeff_firmware, coeff_filename, "misc");
639
if (ret) {
640
dev_dbg(cs35l56->base.dev, "%s: cs_dsp_power_up ret %d\n", __func__, ret);
641
goto err;
642
}
643
644
if (wmfw_filename)
645
dev_dbg(cs35l56->base.dev, "Loaded WMFW Firmware: %s\n", wmfw_filename);
646
647
if (coeff_filename)
648
dev_dbg(cs35l56->base.dev, "Loaded Coefficients: %s\n", coeff_filename);
649
650
/* If we downloaded firmware, reset the device and wait for it to boot */
651
if (firmware_missing && (wmfw_firmware || coeff_firmware)) {
652
cs35l56_system_reset(&cs35l56->base, false);
653
regcache_mark_dirty(cs35l56->base.regmap);
654
ret = cs35l56_wait_for_firmware_boot(&cs35l56->base);
655
if (ret)
656
goto err_powered_up;
657
658
regcache_cache_only(cs35l56->base.regmap, false);
659
}
660
661
/* Disable auto-hibernate so that runtime_pm has control */
662
ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
663
if (ret)
664
goto err_powered_up;
665
666
regcache_sync(cs35l56->base.regmap);
667
668
regmap_clear_bits(cs35l56->base.regmap,
669
cs35l56->base.fw_reg->prot_sts,
670
CS35L56_FIRMWARE_MISSING);
671
cs35l56->base.fw_patched = true;
672
673
ret = cs_dsp_run(&cs35l56->cs_dsp);
674
if (ret)
675
dev_dbg(cs35l56->base.dev, "%s: cs_dsp_run ret %d\n", __func__, ret);
676
677
/* Don't need to check return code, it's not fatal if this fails */
678
cs35l56_hda_apply_calibration(cs35l56);
679
680
ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_AUDIO_REINIT);
681
if (ret)
682
cs_dsp_stop(&cs35l56->cs_dsp);
683
684
cs35l56_log_tuning(&cs35l56->base, &cs35l56->cs_dsp);
685
686
err_powered_up:
687
if (!cs35l56->base.fw_patched)
688
cs_dsp_power_down(&cs35l56->cs_dsp);
689
err:
690
mutex_unlock(&cs35l56->base.irq_lock);
691
err_fw_release:
692
cs35l56_hda_release_firmware_files(wmfw_firmware, wmfw_filename,
693
coeff_firmware, coeff_filename);
694
}
695
696
static void cs35l56_hda_dsp_work(struct work_struct *work)
697
{
698
struct cs35l56_hda *cs35l56 = container_of(work, struct cs35l56_hda, dsp_work);
699
700
cs35l56_hda_fw_load(cs35l56);
701
}
702
703
static ssize_t cs35l56_hda_debugfs_calibrate_write(struct file *file,
704
const char __user *from,
705
size_t count, loff_t *ppos)
706
{
707
struct cs35l56_base *cs35l56_base = file->private_data;
708
ssize_t ret;
709
710
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(cs35l56_base->dev, pm);
711
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
712
if (ret)
713
return ret;
714
715
return cs35l56_calibrate_debugfs_write(cs35l56_base, from, count, ppos);
716
}
717
718
static ssize_t cs35l56_hda_debugfs_cal_temperature_write(struct file *file,
719
const char __user *from,
720
size_t count, loff_t *ppos)
721
{
722
struct cs35l56_base *cs35l56_base = file->private_data;
723
ssize_t ret;
724
725
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(cs35l56_base->dev, pm);
726
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
727
if (ret)
728
return ret;
729
730
return cs35l56_cal_ambient_debugfs_write(cs35l56_base, from, count, ppos);
731
}
732
733
static ssize_t cs35l56_hda_debugfs_cal_data_read(struct file *file,
734
char __user *to,
735
size_t count, loff_t *ppos)
736
{
737
struct cs35l56_base *cs35l56_base = file->private_data;
738
ssize_t ret;
739
740
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(cs35l56_base->dev, pm);
741
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
742
if (ret)
743
return ret;
744
745
return cs35l56_cal_data_debugfs_read(cs35l56_base, to, count, ppos);
746
}
747
748
static ssize_t cs35l56_hda_debugfs_cal_data_write(struct file *file,
749
const char __user *from,
750
size_t count, loff_t *ppos)
751
{
752
struct cs35l56_base *cs35l56_base = file->private_data;
753
struct cs35l56_hda *cs35l56 = cs35l56_hda_from_base(cs35l56_base);
754
ssize_t ret;
755
756
ret = cs35l56_cal_data_debugfs_write(cs35l56_base, from, count, ppos);
757
if (ret == -ENODATA)
758
return count; /* Ignore writes of empty cal blobs */
759
760
if (ret < 0)
761
return ret;
762
763
PM_RUNTIME_ACQUIRE_IF_ENABLED_AUTOSUSPEND(cs35l56_base->dev, pm);
764
ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
765
if (ret)
766
return ret;
767
768
ret = cs35l56_hda_apply_calibration(cs35l56);
769
if (ret == 0)
770
cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_AUDIO_REINIT);
771
else
772
count = -EIO;
773
774
return count;
775
}
776
777
static const struct cs35l56_cal_debugfs_fops cs35l56_hda_cal_debugfs_fops = {
778
.calibrate = {
779
.write = cs35l56_hda_debugfs_calibrate_write,
780
},
781
.cal_temperature = {
782
.write = cs35l56_hda_debugfs_cal_temperature_write,
783
},
784
.cal_data = {
785
.read = cs35l56_hda_debugfs_cal_data_read,
786
.write = cs35l56_hda_debugfs_cal_data_write,
787
},
788
};
789
790
static int cs35l56_hda_bind(struct device *dev, struct device *master, void *master_data)
791
{
792
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
793
struct hda_component_parent *parent = master_data;
794
struct hda_component *comp;
795
796
comp = hda_component_from_index(parent, cs35l56->index);
797
if (!comp)
798
return -EINVAL;
799
800
if (comp->dev)
801
return -EBUSY;
802
803
comp->dev = dev;
804
cs35l56->codec = parent->codec;
805
strscpy(comp->name, dev_name(dev), sizeof(comp->name));
806
comp->playback_hook = cs35l56_hda_playback_hook;
807
808
queue_work(system_long_wq, &cs35l56->dsp_work);
809
810
cs35l56_hda_create_controls(cs35l56);
811
812
#if IS_ENABLED(CONFIG_SND_DEBUG)
813
cs35l56->debugfs_root = debugfs_create_dir(dev_name(cs35l56->base.dev), sound_debugfs_root);
814
cs_dsp_init_debugfs(&cs35l56->cs_dsp, cs35l56->debugfs_root);
815
#endif
816
817
if (IS_ENABLED(CONFIG_SND_HDA_SCODEC_CS35L56_CAL_DEBUGFS))
818
cs35l56_create_cal_debugfs(&cs35l56->base, &cs35l56_hda_cal_debugfs_fops);
819
820
dev_dbg(cs35l56->base.dev, "Bound\n");
821
822
return 0;
823
}
824
825
static void cs35l56_hda_unbind(struct device *dev, struct device *master, void *master_data)
826
{
827
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
828
struct hda_component_parent *parent = master_data;
829
struct hda_component *comp;
830
831
cancel_work_sync(&cs35l56->dsp_work);
832
833
cs35l56_remove_cal_debugfs(&cs35l56->base);
834
cs35l56_hda_remove_controls(cs35l56);
835
836
#if IS_ENABLED(CONFIG_SND_DEBUG)
837
cs_dsp_cleanup_debugfs(&cs35l56->cs_dsp);
838
debugfs_remove_recursive(cs35l56->debugfs_root);
839
#endif
840
841
if (cs35l56->base.fw_patched)
842
cs_dsp_power_down(&cs35l56->cs_dsp);
843
844
comp = hda_component_from_index(parent, cs35l56->index);
845
if (comp && (comp->dev == dev))
846
memset(comp, 0, sizeof(*comp));
847
848
cs35l56->codec = NULL;
849
850
dev_dbg(cs35l56->base.dev, "Unbound\n");
851
}
852
853
static const struct component_ops cs35l56_hda_comp_ops = {
854
.bind = cs35l56_hda_bind,
855
.unbind = cs35l56_hda_unbind,
856
};
857
858
static int cs35l56_hda_system_suspend(struct device *dev)
859
{
860
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
861
862
cs35l56_hda_wait_dsp_ready(cs35l56);
863
864
if (cs35l56->playing)
865
cs35l56_hda_pause(cs35l56);
866
867
cs35l56->suspended = true;
868
869
/*
870
* The interrupt line is normally shared, but after we start suspending
871
* we can't check if our device is the source of an interrupt, and can't
872
* clear it. Prevent this race by temporarily disabling the parent irq
873
* until we reach _no_irq.
874
*/
875
if (cs35l56->base.irq)
876
disable_irq(cs35l56->base.irq);
877
878
return pm_runtime_force_suspend(dev);
879
}
880
881
static int cs35l56_hda_system_suspend_late(struct device *dev)
882
{
883
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
884
885
/*
886
* RESET is usually shared by all amps so it must not be asserted until
887
* all driver instances have done their suspend() stage.
888
*/
889
if (cs35l56->base.reset_gpio) {
890
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
891
cs35l56_wait_min_reset_pulse();
892
}
893
894
return 0;
895
}
896
897
static int cs35l56_hda_system_suspend_no_irq(struct device *dev)
898
{
899
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
900
901
/* Handlers are now disabled so the parent IRQ can safely be re-enabled. */
902
if (cs35l56->base.irq)
903
enable_irq(cs35l56->base.irq);
904
905
return 0;
906
}
907
908
static int cs35l56_hda_system_resume_no_irq(struct device *dev)
909
{
910
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
911
912
/*
913
* WAKE interrupts unmask if the CS35L56 hibernates, which can cause
914
* spurious interrupts, and the interrupt line is normally shared.
915
* We can't check if our device is the source of an interrupt, and can't
916
* clear it, until it has fully resumed. Prevent this race by temporarily
917
* disabling the parent irq until we complete resume().
918
*/
919
if (cs35l56->base.irq)
920
disable_irq(cs35l56->base.irq);
921
922
return 0;
923
}
924
925
static int cs35l56_hda_system_resume_early(struct device *dev)
926
{
927
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
928
929
/* Ensure a spec-compliant RESET pulse. */
930
if (cs35l56->base.reset_gpio) {
931
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
932
cs35l56_wait_min_reset_pulse();
933
934
/* Release shared RESET before drivers start resume(). */
935
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1);
936
cs35l56_wait_control_port_ready();
937
}
938
939
return 0;
940
}
941
942
static int cs35l56_hda_system_resume(struct device *dev)
943
{
944
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
945
int ret;
946
947
/* Undo pm_runtime_force_suspend() before re-enabling the irq */
948
ret = pm_runtime_force_resume(dev);
949
if (cs35l56->base.irq)
950
enable_irq(cs35l56->base.irq);
951
952
if (ret)
953
return ret;
954
955
cs35l56->suspended = false;
956
957
if (!cs35l56->codec)
958
return 0;
959
960
ret = cs35l56_is_fw_reload_needed(&cs35l56->base);
961
dev_dbg(cs35l56->base.dev, "fw_reload_needed: %d\n", ret);
962
if (ret > 0)
963
queue_work(system_long_wq, &cs35l56->dsp_work);
964
965
if (cs35l56->playing)
966
cs35l56_hda_play(cs35l56);
967
968
return 0;
969
}
970
971
static int cs35l56_hda_fixup_yoga9(struct cs35l56_hda *cs35l56, int *bus_addr)
972
{
973
/* The cirrus,dev-index property has the wrong values */
974
switch (*bus_addr) {
975
case 0x30:
976
cs35l56->index = 1;
977
return 0;
978
case 0x31:
979
cs35l56->index = 0;
980
return 0;
981
default:
982
/* There is a pseudo-address for broadcast to both amps - ignore it */
983
dev_dbg(cs35l56->base.dev, "Ignoring I2C address %#x\n", *bus_addr);
984
return 0;
985
}
986
}
987
988
static const struct {
989
const char *sub;
990
int (*fixup_fn)(struct cs35l56_hda *cs35l56, int *bus_addr);
991
} cs35l56_hda_fixups[] = {
992
{
993
.sub = "17AA390B", /* Lenovo Yoga Book 9i GenX */
994
.fixup_fn = cs35l56_hda_fixup_yoga9,
995
},
996
};
997
998
static int cs35l56_hda_apply_platform_fixups(struct cs35l56_hda *cs35l56, const char *sub,
999
int *bus_addr)
1000
{
1001
int i;
1002
1003
if (IS_ERR(sub))
1004
return 0;
1005
1006
for (i = 0; i < ARRAY_SIZE(cs35l56_hda_fixups); i++) {
1007
if (strcasecmp(cs35l56_hda_fixups[i].sub, sub) == 0) {
1008
dev_dbg(cs35l56->base.dev, "Applying fixup for %s\n",
1009
cs35l56_hda_fixups[i].sub);
1010
return (cs35l56_hda_fixups[i].fixup_fn)(cs35l56, bus_addr);
1011
}
1012
}
1013
1014
return 0;
1015
}
1016
1017
static int cs35l56_hda_read_acpi(struct cs35l56_hda *cs35l56, int hid, int id)
1018
{
1019
u32 values[HDA_MAX_COMPONENTS];
1020
char hid_string[8];
1021
struct acpi_device *adev;
1022
const char *property, *sub;
1023
size_t nval;
1024
int i, ret;
1025
1026
/*
1027
* ACPI_COMPANION isn't available when this driver was instantiated by
1028
* the serial-multi-instantiate driver, so lookup the node by HID
1029
*/
1030
if (!ACPI_COMPANION(cs35l56->base.dev)) {
1031
snprintf(hid_string, sizeof(hid_string), "CSC%04X", hid);
1032
adev = acpi_dev_get_first_match_dev(hid_string, NULL, -1);
1033
if (!adev) {
1034
dev_err(cs35l56->base.dev, "Failed to find an ACPI device for %s\n",
1035
dev_name(cs35l56->base.dev));
1036
return -ENODEV;
1037
}
1038
ACPI_COMPANION_SET(cs35l56->base.dev, adev);
1039
}
1040
1041
/* Initialize things that could be overwritten by a fixup */
1042
cs35l56->index = -1;
1043
1044
sub = acpi_get_subsystem_id(ACPI_HANDLE(cs35l56->base.dev));
1045
ret = cs35l56_hda_apply_platform_fixups(cs35l56, sub, &id);
1046
if (ret)
1047
return ret;
1048
1049
if (cs35l56->index == -1) {
1050
property = "cirrus,dev-index";
1051
ret = device_property_count_u32(cs35l56->base.dev, property);
1052
if (ret <= 0)
1053
goto err;
1054
1055
if (ret > ARRAY_SIZE(values)) {
1056
ret = -EINVAL;
1057
goto err;
1058
}
1059
nval = ret;
1060
1061
ret = device_property_read_u32_array(cs35l56->base.dev, property, values, nval);
1062
if (ret)
1063
goto err;
1064
1065
for (i = 0; i < nval; i++) {
1066
if (values[i] == id) {
1067
cs35l56->index = i;
1068
break;
1069
}
1070
}
1071
1072
/*
1073
* It's not an error for the ID to be missing: for I2C there can be
1074
* an alias address that is not a real device. So reject silently.
1075
*/
1076
if (cs35l56->index == -1) {
1077
dev_dbg(cs35l56->base.dev, "No index found in %s\n", property);
1078
ret = -ENODEV;
1079
goto err;
1080
}
1081
}
1082
1083
if (IS_ERR(sub)) {
1084
dev_info(cs35l56->base.dev,
1085
"Read ACPI _SUB failed(%ld): fallback to generic firmware\n",
1086
PTR_ERR(sub));
1087
} else {
1088
ret = cirrus_scodec_get_speaker_id(cs35l56->base.dev, cs35l56->index, nval, -1);
1089
if (ret == -ENOENT) {
1090
cs35l56->system_name = sub;
1091
} else if (ret >= 0) {
1092
cs35l56->system_name = kasprintf(GFP_KERNEL, "%s-spkid%d", sub, ret);
1093
kfree(sub);
1094
if (!cs35l56->system_name)
1095
return -ENOMEM;
1096
} else {
1097
return ret;
1098
}
1099
}
1100
1101
cs35l56->base.reset_gpio = devm_gpiod_get_index_optional(cs35l56->base.dev,
1102
"reset",
1103
cs35l56->index,
1104
GPIOD_OUT_LOW);
1105
if (IS_ERR(cs35l56->base.reset_gpio)) {
1106
ret = PTR_ERR(cs35l56->base.reset_gpio);
1107
1108
/*
1109
* If RESET is shared the first amp to probe will grab the reset
1110
* line and reset all the amps
1111
*/
1112
if (ret != -EBUSY)
1113
return dev_err_probe(cs35l56->base.dev, ret, "Failed to get reset GPIO\n");
1114
1115
dev_info(cs35l56->base.dev, "Reset GPIO busy, assume shared reset\n");
1116
cs35l56->base.reset_gpio = NULL;
1117
}
1118
1119
return 0;
1120
1121
err:
1122
if (ret != -ENODEV)
1123
dev_err(cs35l56->base.dev, "Failed property %s: %d\n", property, ret);
1124
1125
return ret;
1126
}
1127
1128
int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int hid, int id)
1129
{
1130
int ret;
1131
1132
mutex_init(&cs35l56->base.irq_lock);
1133
dev_set_drvdata(cs35l56->base.dev, cs35l56);
1134
1135
INIT_WORK(&cs35l56->dsp_work, cs35l56_hda_dsp_work);
1136
1137
ret = cs35l56_hda_read_acpi(cs35l56, hid, id);
1138
if (ret)
1139
goto err;
1140
1141
cs35l56->amp_name = devm_kasprintf(cs35l56->base.dev, GFP_KERNEL, "AMP%d",
1142
cs35l56->index + 1);
1143
if (!cs35l56->amp_name) {
1144
ret = -ENOMEM;
1145
goto err;
1146
}
1147
1148
cs35l56->base.type = hid & 0xff;
1149
cs35l56->base.cal_index = cs35l56->index;
1150
1151
cs35l56_init_cs_dsp(&cs35l56->base, &cs35l56->cs_dsp);
1152
cs35l56->cs_dsp.client_ops = &cs35l56_hda_client_ops;
1153
1154
if (cs35l56->base.reset_gpio) {
1155
dev_dbg(cs35l56->base.dev, "Hard reset\n");
1156
1157
/*
1158
* The GPIOD_OUT_LOW to *_gpiod_get_*() will be ignored if the
1159
* ACPI defines a different default state. So explicitly set low.
1160
*/
1161
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
1162
cs35l56_wait_min_reset_pulse();
1163
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 1);
1164
}
1165
1166
ret = cs35l56_hw_init(&cs35l56->base);
1167
if (ret < 0)
1168
goto err;
1169
1170
/* Reset the device and wait for it to boot */
1171
cs35l56_system_reset(&cs35l56->base, false);
1172
ret = cs35l56_wait_for_firmware_boot(&cs35l56->base);
1173
if (ret)
1174
goto err;
1175
1176
regcache_cache_only(cs35l56->base.regmap, false);
1177
1178
ret = cs35l56_set_patch(&cs35l56->base);
1179
if (ret)
1180
goto err;
1181
1182
regcache_mark_dirty(cs35l56->base.regmap);
1183
regcache_sync(cs35l56->base.regmap);
1184
1185
/* Disable auto-hibernate so that runtime_pm has control */
1186
ret = cs35l56_mbox_send(&cs35l56->base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
1187
if (ret)
1188
goto err;
1189
1190
ret = cs35l56_get_calibration(&cs35l56->base);
1191
if (ret)
1192
goto err;
1193
1194
ret = cs_dsp_halo_init(&cs35l56->cs_dsp);
1195
if (ret) {
1196
dev_err_probe(cs35l56->base.dev, ret, "cs_dsp_halo_init failed\n");
1197
goto err;
1198
}
1199
1200
dev_info(cs35l56->base.dev, "DSP system name: '%s', amp name: '%s'\n",
1201
cs35l56->system_name, cs35l56->amp_name);
1202
1203
regmap_multi_reg_write(cs35l56->base.regmap, cs35l56_hda_dai_config,
1204
ARRAY_SIZE(cs35l56_hda_dai_config));
1205
1206
/*
1207
* By default only enable one ASP1TXn, where n=amplifier index,
1208
* This prevents multiple amps trying to drive the same slot.
1209
*/
1210
cs35l56->asp_tx_mask = BIT(cs35l56->index);
1211
1212
pm_runtime_set_autosuspend_delay(cs35l56->base.dev, 3000);
1213
pm_runtime_use_autosuspend(cs35l56->base.dev);
1214
pm_runtime_set_active(cs35l56->base.dev);
1215
pm_runtime_mark_last_busy(cs35l56->base.dev);
1216
pm_runtime_enable(cs35l56->base.dev);
1217
1218
cs35l56->base.init_done = true;
1219
1220
ret = component_add(cs35l56->base.dev, &cs35l56_hda_comp_ops);
1221
if (ret) {
1222
dev_err(cs35l56->base.dev, "Register component failed: %d\n", ret);
1223
goto pm_err;
1224
}
1225
1226
return 0;
1227
1228
pm_err:
1229
pm_runtime_disable(cs35l56->base.dev);
1230
cs_dsp_remove(&cs35l56->cs_dsp);
1231
err:
1232
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
1233
1234
return ret;
1235
}
1236
EXPORT_SYMBOL_NS_GPL(cs35l56_hda_common_probe, "SND_HDA_SCODEC_CS35L56");
1237
1238
void cs35l56_hda_remove(struct device *dev)
1239
{
1240
struct cs35l56_hda *cs35l56 = dev_get_drvdata(dev);
1241
1242
component_del(cs35l56->base.dev, &cs35l56_hda_comp_ops);
1243
1244
pm_runtime_dont_use_autosuspend(cs35l56->base.dev);
1245
pm_runtime_get_sync(cs35l56->base.dev);
1246
pm_runtime_disable(cs35l56->base.dev);
1247
1248
cs_dsp_remove(&cs35l56->cs_dsp);
1249
1250
kfree(cs35l56->system_name);
1251
pm_runtime_put_noidle(cs35l56->base.dev);
1252
1253
gpiod_set_value_cansleep(cs35l56->base.reset_gpio, 0);
1254
}
1255
EXPORT_SYMBOL_NS_GPL(cs35l56_hda_remove, "SND_HDA_SCODEC_CS35L56");
1256
1257
const struct dev_pm_ops cs35l56_hda_pm_ops = {
1258
RUNTIME_PM_OPS(cs35l56_hda_runtime_suspend, cs35l56_hda_runtime_resume, NULL)
1259
SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend, cs35l56_hda_system_resume)
1260
LATE_SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend_late,
1261
cs35l56_hda_system_resume_early)
1262
NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l56_hda_system_suspend_no_irq,
1263
cs35l56_hda_system_resume_no_irq)
1264
};
1265
EXPORT_SYMBOL_NS_GPL(cs35l56_hda_pm_ops, "SND_HDA_SCODEC_CS35L56");
1266
1267
MODULE_DESCRIPTION("CS35L56 HDA Driver");
1268
MODULE_IMPORT_NS("FW_CS_DSP");
1269
MODULE_IMPORT_NS("SND_HDA_CIRRUS_SCODEC");
1270
MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED");
1271
MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB");
1272
MODULE_AUTHOR("Richard Fitzgerald <[email protected]>");
1273
MODULE_AUTHOR("Simon Trimmer <[email protected]>");
1274
MODULE_LICENSE("GPL");
1275
MODULE_FIRMWARE("cirrus/cs35l54-*.wmfw");
1276
MODULE_FIRMWARE("cirrus/cs35l54-*.bin");
1277
MODULE_FIRMWARE("cirrus/cs35l56-*.wmfw");
1278
MODULE_FIRMWARE("cirrus/cs35l56-*.bin");
1279
1280