spacepaste

  1.  
  2. --- a/sound/pci/hda/patch_ca0132.c 2018-04-01 17:20:27.000000000 -0400
  3. +++ b/sound/pci/hda/patch_ca0132.c 2018-05-02 07:47:08.000000000 -0400
  4. @@ -29,6 +29,9 @@
  5. #include <linux/firmware.h>
  6. #include <linux/kernel.h>
  7. #include <sound/core.h>
  8. +#include <linux/types.h>
  9. +#include <linux/io.h>
  10. +#include <linux/pci.h>
  11. #include "hda_codec.h"
  12. #include "hda_local.h"
  13. #include "hda_auto_parser.h"
  14. @@ -42,6 +45,8 @@
  15. #define FLOAT_ZERO 0x00000000
  16. #define FLOAT_ONE 0x3f800000
  17. #define FLOAT_TWO 0x40000000
  18. +#define FLOAT_THREE 0x40400000
  19. +#define FLOAT_EIGHT 0x41000000
  20. #define FLOAT_MINUS_5 0xc0a00000
  21. #define UNSOL_TAG_DSP 0x16
  22. @@ -72,16 +77,22 @@
  23. #define SCP_GET 1
  24. #define EFX_FILE "ctefx.bin"
  25. +#define SBZ_EFX_FILE "ctefx-sbz.bin"
  26. +#define R3DI_EFX_FILE "ctefx-r3di.bin"
  27. #ifdef CONFIG_SND_HDA_CODEC_CA0132_DSP
  28. MODULE_FIRMWARE(EFX_FILE);
  29. +MODULE_FIRMWARE(SBZ_EFX_FILE);
  30. +MODULE_FIRMWARE(R3DI_EFX_FILE);
  31. #endif
  32. -static char *dirstr[2] = { "Playback", "Capture" };
  33. +static const char *dirstr[2] = { "Playback", "Capture" };
  34. +#define NUM_OF_OUTPUTS 3
  35. enum {
  36. SPEAKER_OUT,
  37. - HEADPHONE_OUT
  38. + HEADPHONE_OUT,
  39. + SURROUND_OUT
  40. };
  41. enum {
  42. @@ -89,6 +100,15 @@
  43. LINE_MIC_IN
  44. };
  45. +/* Strings for Input Source Enum Control */
  46. +static const char *in_src_str[3] = {"Rear Mic", "Line", "Front Mic" };
  47. +#define IN_SRC_NUM_OF_INPUTS 3
  48. +enum {
  49. + REAR_MIC,
  50. + REAR_LINE_IN,
  51. + FRONT_MIC,
  52. +};
  53. +
  54. enum {
  55. #define VNODE_START_NID 0x80
  56. VNID_SPK = VNODE_START_NID, /* Speaker vnid */
  57. @@ -122,13 +142,26 @@
  58. VOICEFX = IN_EFFECT_END_NID,
  59. PLAY_ENHANCEMENT,
  60. CRYSTAL_VOICE,
  61. - EFFECT_END_NID
  62. + EFFECT_END_NID,
  63. + OUTPUT_SOURCE_ENUM,
  64. + INPUT_SOURCE_ENUM,
  65. + XBASS_XOVER,
  66. + EQ_PRESET_ENUM,
  67. + SMART_VOLUME_ENUM,
  68. + MIC_BOOST_ENUM
  69. #define EFFECTS_COUNT (EFFECT_END_NID - EFFECT_START_NID)
  70. };
  71. /* Effects values size*/
  72. #define EFFECT_VALS_MAX_COUNT 12
  73. +/* Amount of effect level sliders for ca0132_alt controls. */
  74. +#define EFFECT_LEVEL_SLIDERS 5
  75. +/* Default values for the effect slider controls, they are in order of their
  76. + * effect NID's. Surround, Crystalizer, Dialog Plus, Smart Volume, and then
  77. + * X-bass. */
  78. +static const unsigned int effect_slider_defaults[] = {67, 65, 50, 74, 50};
  79. +
  80. /* Latency introduced by DSP blocks in milliseconds. */
  81. #define DSP_CAPTURE_INIT_LATENCY 0
  82. #define DSP_CRYSTAL_VOICE_LATENCY 124
  83. @@ -472,6 +505,161 @@
  84. }
  85. };
  86. +/* ca0132 EQ presets, taken from Windows Sound Blaster Z Driver */
  87. +
  88. +#define EQ_PRESET_MAX_PARAM_COUNT 11
  89. +
  90. +struct ct_eq {
  91. + char *name;
  92. + hda_nid_t nid;
  93. + int mid;
  94. + int reqs[EQ_PRESET_MAX_PARAM_COUNT]; /*effect module request*/
  95. +};
  96. +
  97. +struct ct_eq_preset {
  98. + char *name; /*preset name*/
  99. + unsigned int vals[EQ_PRESET_MAX_PARAM_COUNT];
  100. +};
  101. +
  102. +static struct ct_eq ca0132_alt_eq_enum = {
  103. + .name = "FX: Equalizer Preset Switch",
  104. + .nid = EQ_PRESET_ENUM,
  105. + .mid = 0x96,
  106. + .reqs = {10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}
  107. +};
  108. +
  109. +
  110. +static struct ct_eq_preset ca0132_alt_eq_presets[] = {
  111. + { .name = "Flat",
  112. + .vals = { 0x00000000, 0x00000000, 0x00000000,
  113. + 0x00000000, 0x00000000, 0x00000000,
  114. + 0x00000000, 0x00000000, 0x00000000,
  115. + 0x00000000, 0x00000000 }
  116. + },
  117. + { .name = "Acoustic",
  118. + .vals = { 0x00000000, 0x00000000, 0x3F8CCCCD,
  119. + 0x40000000, 0x00000000, 0x00000000,
  120. + 0x00000000, 0x00000000, 0x40000000,
  121. + 0x40000000, 0x40000000 }
  122. + },
  123. + { .name = "Classical",
  124. + .vals = { 0x00000000, 0x00000000, 0x40C00000,
  125. + 0x40C00000, 0x40466666, 0x00000000,
  126. + 0x00000000, 0x00000000, 0x00000000,
  127. + 0x40466666, 0x40466666 }
  128. + },
  129. + { .name = "Country",
  130. + .vals = { 0x00000000, 0xBF99999A, 0x00000000,
  131. + 0x3FA66666, 0x3FA66666, 0x3F8CCCCD,
  132. + 0x00000000, 0x00000000, 0x40000000,
  133. + 0x40466666, 0x40800000 }
  134. + },
  135. + { .name = "Dance",
  136. + .vals = { 0x00000000, 0xBF99999A, 0x40000000,
  137. + 0x40466666, 0x40866666, 0xBF99999A,
  138. + 0xBF99999A, 0x00000000, 0x00000000,
  139. + 0x40800000, 0x40800000 }
  140. + },
  141. + { .name = "Jazz",
  142. + .vals = { 0x00000000, 0x00000000, 0x00000000,
  143. + 0x3F8CCCCD, 0x40800000, 0x40800000,
  144. + 0x40800000, 0x00000000, 0x3F8CCCCD,
  145. + 0x40466666, 0x40466666 }
  146. + },
  147. + { .name = "New Age",
  148. + .vals = { 0x00000000, 0x00000000, 0x40000000,
  149. + 0x40000000, 0x00000000, 0x00000000,
  150. + 0x00000000, 0x3F8CCCCD, 0x40000000,
  151. + 0x40000000, 0x40000000 }
  152. + },
  153. + { .name = "Pop",
  154. + .vals = { 0x00000000, 0xBFCCCCCD, 0x00000000,
  155. + 0x40000000, 0x40000000, 0x00000000,
  156. + 0xBF99999A, 0xBF99999A, 0x00000000,
  157. + 0x40466666, 0x40C00000 }
  158. + },
  159. + { .name = "Rock",
  160. + .vals = { 0x00000000, 0xBF99999A, 0xBF99999A,
  161. + 0x3F8CCCCD, 0x40000000, 0xBF99999A,
  162. + 0xBF99999A, 0x00000000, 0x00000000,
  163. + 0x40800000, 0x40800000 }
  164. + },
  165. + { .name = "Vocal",
  166. + .vals = { 0x00000000, 0xC0000000, 0xBF99999A,
  167. + 0xBF99999A, 0x00000000, 0x40466666,
  168. + 0x40800000, 0x40466666, 0x00000000,
  169. + 0x00000000, 0x3F8CCCCD }
  170. + }
  171. +};
  172. +
  173. +/* DSP command sequences for ca0132_alt_select_out */
  174. +#define ALT_OUT_SET_MAX_COMMANDS 9 /* Max number of commands in sequence */
  175. +struct ca0132_alt_out_set {
  176. + char *name; /*preset name*/
  177. + unsigned char commands;
  178. + unsigned int mids[ALT_OUT_SET_MAX_COMMANDS];
  179. + unsigned int reqs[ALT_OUT_SET_MAX_COMMANDS];
  180. + unsigned int vals[ALT_OUT_SET_MAX_COMMANDS];
  181. +};
  182. +
  183. +static struct ca0132_alt_out_set alt_out_presets[] = {
  184. + { .name = "Line Out",
  185. + .commands = 7,
  186. + .mids = { 0x96, 0x96, 0x96, 0x8F,
  187. + 0x96, 0x96, 0x96 },
  188. + .reqs = { 0x19, 0x17, 0x18, 0x01,
  189. + 0x1F, 0x15, 0x3A },
  190. + .vals = { 0x3F000000, 0x42A00000, 0x00000000,
  191. + 0x00000000, 0x00000000, 0x00000000,
  192. + 0x00000000 }
  193. + },
  194. + { .name = "Headphone",
  195. + .commands = 7,
  196. + .mids = { 0x96, 0x96, 0x96, 0x8F,
  197. + 0x96, 0x96, 0x96 },
  198. + .reqs = { 0x19, 0x17, 0x18, 0x01,
  199. + 0x1F, 0x15, 0x3A },
  200. + .vals = { 0x3F000000, 0x42A00000, 0x00000000,
  201. + 0x00000000, 0x00000000, 0x00000000,
  202. + 0x00000000 }
  203. + },
  204. + { .name = "Surround",
  205. + .commands = 8,
  206. + .mids = { 0x96, 0x8F, 0x96, 0x96,
  207. + 0x96, 0x96, 0x96, 0x96 },
  208. + .reqs = { 0x18, 0x01, 0x1F, 0x15,
  209. + 0x3A, 0x1A, 0x1B, 0x1C },
  210. + .vals = { 0x00000000, 0x00000000, 0x00000000,
  211. + 0x00000000, 0x00000000, 0x00000000,
  212. + 0x00000000, 0x00000000 }
  213. + }
  214. +};
  215. +
  216. +/*
  217. + * DSP volume setting structs. Req 1 is left volume, req 2 is right volume,
  218. + * and I don't know what the third req is, but it's always zero. I assume it's
  219. + * some sort of update or set command to tell the DSP there's new volume info.
  220. + */
  221. +#define DSP_VOL_OUT 0
  222. +#define DSP_VOL_IN 1
  223. +
  224. +struct ct_dsp_volume_ctl {
  225. + hda_nid_t vnid;
  226. + int mid; /* module ID*/
  227. + unsigned int reqs[3]; /* scp req ID */
  228. +};
  229. +
  230. +static struct ct_dsp_volume_ctl ca0132_alt_vol_ctls[] = {
  231. + { .vnid = VNID_SPK,
  232. + .mid = 0x32,
  233. + .reqs = {3, 4, 2}
  234. + },
  235. + { .vnid = VNID_MIC,
  236. + .mid = 0x37,
  237. + .reqs = {2, 3, 1}
  238. + }
  239. +};
  240. +
  241. enum hda_cmd_vendor_io {
  242. /* for DspIO node */
  243. VENDOR_DSPIO_SCP_WRITE_DATA_LOW = 0x000,
  244. @@ -703,6 +891,7 @@
  245. const struct hda_verb *base_init_verbs;
  246. const struct hda_verb *base_exit_verbs;
  247. const struct hda_verb *chip_init_verbs;
  248. + const struct hda_verb *sbz_init_verbs;
  249. struct hda_verb *spec_init_verbs;
  250. struct auto_pin_cfg autocfg;
  251. @@ -719,6 +908,7 @@
  252. hda_nid_t shared_mic_nid;
  253. hda_nid_t shared_out_nid;
  254. hda_nid_t unsol_tag_hp;
  255. + hda_nid_t unsol_tag_front_hp; /* for desktop ca0132 codecs */
  256. hda_nid_t unsol_tag_amic1;
  257. /* chip access */
  258. @@ -734,6 +924,9 @@
  259. unsigned int scp_resp_header;
  260. unsigned int scp_resp_data[4];
  261. unsigned int scp_resp_count;
  262. + bool alt_firmware_present;
  263. + bool startup_check_entered;
  264. + bool dsp_reload;
  265. /* mixer and effects related */
  266. unsigned char dmic_ctl;
  267. @@ -746,6 +939,17 @@
  268. long effects_switch[EFFECTS_COUNT];
  269. long voicefx_val;
  270. long cur_mic_boost;
  271. + /* ca0132_alt control related values */
  272. + unsigned char in_enum_val;
  273. + unsigned char out_enum_val;
  274. + unsigned char mic_boost_enum_val;
  275. + unsigned char smart_volume_setting;
  276. + long fx_ctl_val[EFFECT_LEVEL_SLIDERS];
  277. + long xbass_xover_freq;
  278. + long eq_preset_val;
  279. + unsigned int tlv[4];
  280. + struct hda_vmaster_mute_hook vmaster_mute;
  281. +
  282. struct hda_codec *codec;
  283. struct delayed_work unsol_hp_work;
  284. @@ -754,6 +958,25 @@
  285. #ifdef ENABLE_TUNING_CONTROLS
  286. long cur_ctl_vals[TUNING_CTLS_COUNT];
  287. #endif
  288. + /*
  289. + * Sound Blaster Z PCI region 2 iomem, used for input and output
  290. + * switching, and other unknown commands.
  291. + */
  292. + void __iomem *mem_base;
  293. +
  294. + /*
  295. + * Whether or not to use the alt functions like alt_select_out,
  296. + * alt_select_in, etc. Only used on desktop codecs for now, because of
  297. + * surround sound support.
  298. + */
  299. + bool use_alt_functions;
  300. +
  301. + /*
  302. + * Whether or not to use alt controls: volume effect sliders, EQ
  303. + * presets, smart volume presets, and new control names with FX prefix.
  304. + * Renames PlayEnhancement and CrystalVoice too.
  305. + */
  306. + bool use_alt_controls;
  307. };
  308. /*
  309. @@ -762,6 +985,8 @@
  310. enum {
  311. QUIRK_NONE,
  312. QUIRK_ALIENWARE,
  313. + QUIRK_SBZ,
  314. + QUIRK_R3DI,
  315. };
  316. static const struct hda_pintbl alienware_pincfgs[] = {
  317. @@ -778,10 +1003,44 @@
  318. {}
  319. };
  320. +/* Sound Blaster Z pin configs taken from Windows Driver */
  321. +static const struct hda_pintbl sbz_pincfgs[] = {
  322. + { 0x0b, 0x01017010 }, /* Port G -- Lineout FRONT L/R */
  323. + { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */
  324. + { 0x0d, 0x014510f0 }, /* Digital Out */
  325. + { 0x0e, 0x01c510f0 }, /* SPDIF In */
  326. + { 0x0f, 0x0221701f }, /* Port A -- BackPanel HP */
  327. + { 0x10, 0x01017012 }, /* Port D -- Center/LFE or FP Hp */
  328. + { 0x11, 0x01017014 }, /* Port B -- LineMicIn2 / Rear L/R */
  329. + { 0x12, 0x01a170f0 }, /* Port C -- LineIn1 */
  330. + { 0x13, 0x908700f0 }, /* What U Hear In*/
  331. + { 0x18, 0x50d000f0 }, /* N/A */
  332. + {}
  333. +};
  334. +
  335. +/* Recon3D integrated pin configs taken from Windows Driver */
  336. +static const struct hda_pintbl r3di_pincfgs[] = {
  337. + { 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */
  338. + { 0x0c, 0x014510f0 }, /* SPDIF Out 1 */
  339. + { 0x0d, 0x014510f0 }, /* Digital Out */
  340. + { 0x0e, 0x41c520f0 }, /* SPDIF In */
  341. + { 0x0f, 0x0221401f }, /* Port A -- BackPanel HP */
  342. + { 0x10, 0x01016011 }, /* Port D -- Center/LFE or FP Hp */
  343. + { 0x11, 0x01011014 }, /* Port B -- LineMicIn2 / Rear L/R */
  344. + { 0x12, 0x02a090f0 }, /* Port C -- LineIn1 */
  345. + { 0x13, 0x908700f0 }, /* What U Hear In*/
  346. + { 0x18, 0x500000f0 }, /* N/A */
  347. + {}
  348. +};
  349. +
  350. static const struct snd_pci_quirk ca0132_quirks[] = {
  351. SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE),
  352. SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE),
  353. SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE),
  354. + SND_PCI_QUIRK(0x1102, 0x0010, "Sound Blaster Z", QUIRK_SBZ),
  355. + SND_PCI_QUIRK(0x1102, 0x0023, "Sound Blaster Z", QUIRK_SBZ),
  356. + SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
  357. + SND_PCI_QUIRK(0x1458, 0xA036, "Recon3Di", QUIRK_R3DI),
  358. {}
  359. };
  360. @@ -965,6 +1224,29 @@
  361. }
  362. /*
  363. + * Write given value to the given address through the chip I/O widget.
  364. + * not protected by the Mutex
  365. + */
  366. +static int chipio_write_no_mutex(struct hda_codec *codec,
  367. + unsigned int chip_addx, const unsigned int data)
  368. +{
  369. + int err;
  370. +
  371. +
  372. + /* write the address, and if successful proceed to write data */
  373. + err = chipio_write_address(codec, chip_addx);
  374. + if (err < 0)
  375. + goto exit;
  376. +
  377. + err = chipio_write_data(codec, data);
  378. + if (err < 0)
  379. + goto exit;
  380. +
  381. +exit:
  382. + return err;
  383. +}
  384. +
  385. +/*
  386. * Write multiple values to the given address through the chip I/O widget.
  387. * protected by the Mutex
  388. */
  389. @@ -1058,6 +1340,80 @@
  390. }
  391. /*
  392. + * Set chip parameters through the chip I/O widget. NO MUTEX.
  393. + */
  394. +static void chipio_set_control_param_no_mutex(struct hda_codec *codec,
  395. + enum control_param_id param_id, int param_val)
  396. +{
  397. + int val;
  398. +
  399. + codec_dbg(codec, "chipio_param ID: %d val: 0x%02x \n", param_id, param_val);
  400. +
  401. + if ((param_id < 32) && (param_val < 8)) {
  402. + val = (param_val << 5) | (param_id);
  403. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  404. + VENDOR_CHIPIO_PARAM_SET, val);
  405. + } else {
  406. + if (chipio_send(codec, VENDOR_CHIPIO_STATUS, 0) == 0) {
  407. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  408. + VENDOR_CHIPIO_PARAM_EX_ID_SET,
  409. + param_id);
  410. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  411. + VENDOR_CHIPIO_PARAM_EX_VALUE_SET,
  412. + param_val);
  413. + }
  414. + }
  415. +}
  416. +/*
  417. + * Connect stream to a source point, and then connect
  418. + * that source point to a destination point.
  419. + */
  420. +static void chipio_set_stream_source_dest(struct hda_codec *codec,
  421. + int streamid, int source_point, int dest_point)
  422. +{
  423. +
  424. + chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_STREAM_ID, streamid);
  425. + chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_STREAM_SOURCE_CONN_POINT,
  426. + source_point);
  427. + chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_STREAM_DEST_CONN_POINT,
  428. + dest_point);
  429. +}
  430. +
  431. +/*
  432. + * Set number of channels in the selected stream.
  433. + */
  434. +static void chipio_set_stream_channels(struct hda_codec *codec,
  435. + int streamid, unsigned int channels)
  436. +{
  437. + chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_STREAM_ID, streamid);
  438. + chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_STREAMS_CHANNELS,
  439. + channels);
  440. +}
  441. +
  442. +/*
  443. + * Enable/Disable audio stream.
  444. + */
  445. +static void chipio_set_stream_control(struct hda_codec *codec,
  446. + int streamid, int enable)
  447. +{
  448. + chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_STREAM_ID, streamid);
  449. + chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_STREAM_CONTROL,
  450. + enable);
  451. +}
  452. +
  453. +
  454. +/*
  455. + * Set sampling rate of the connection point. NO MUTEX.
  456. + */
  457. +static void chipio_set_conn_rate_no_mutex(struct hda_codec *codec,
  458. + int connid, enum ca0132_sample_rate rate)
  459. +{
  460. + chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_CONN_POINT_ID, connid);
  461. + chipio_set_control_param_no_mutex(codec, CONTROL_PARAM_CONN_POINT_SAMPLE_RATE,
  462. + rate);
  463. +}
  464. +
  465. +/*
  466. * Set sampling rate of the connection point.
  467. */
  468. static void chipio_set_conn_rate(struct hda_codec *codec,
  469. @@ -1420,8 +1776,8 @@
  470. * Returns zero or a negative error code.
  471. */
  472. static int dspio_scp(struct hda_codec *codec,
  473. - int mod_id, int req, int dir, void *data, unsigned int len,
  474. - void *reply, unsigned int *reply_len)
  475. + int mod_id, int src_id, int req, int dir, const void *data,
  476. + unsigned int len, void *reply, unsigned int *reply_len)
  477. {
  478. int status = 0;
  479. struct scp_msg scp_send, scp_reply;
  480. @@ -1445,7 +1801,7 @@
  481. return -EINVAL;
  482. }
  483. - scp_send.hdr = make_scp_header(mod_id, 0x20, (dir == SCP_GET), req,
  484. + scp_send.hdr = make_scp_header(mod_id, src_id, (dir == SCP_GET), req,
  485. 0, 0, 0, len/sizeof(unsigned int));
  486. if (data != NULL && len > 0) {
  487. len = min((unsigned int)(sizeof(scp_send.data)), len);
  488. @@ -1502,15 +1858,24 @@
  489. * Set DSP parameters
  490. */
  491. static int dspio_set_param(struct hda_codec *codec, int mod_id,
  492. - int req, void *data, unsigned int len)
  493. + int src_id, int req, const void *data, unsigned int len)
  494. {
  495. - return dspio_scp(codec, mod_id, req, SCP_SET, data, len, NULL, NULL);
  496. + return dspio_scp(codec, mod_id, src_id, req, SCP_SET, data, len, NULL,
  497. + NULL);
  498. }
  499. static int dspio_set_uint_param(struct hda_codec *codec, int mod_id,
  500. - int req, unsigned int data)
  501. + int req, const unsigned int data)
  502. +{
  503. + return dspio_set_param(codec, mod_id, 0x20, req, &data,
  504. + sizeof(unsigned int));
  505. +}
  506. +
  507. +static int dspio_set_uint_param_no_source(struct hda_codec *codec, int mod_id,
  508. + int req, const unsigned int data)
  509. {
  510. - return dspio_set_param(codec, mod_id, req, &data, sizeof(unsigned int));
  511. + return dspio_set_param(codec, mod_id, 0x00, req, &data,
  512. + sizeof(unsigned int));
  513. }
  514. /*
  515. @@ -1522,8 +1887,9 @@
  516. unsigned int size = sizeof(dma_chan);
  517. codec_dbg(codec, " dspio_alloc_dma_chan() -- begin\n");
  518. - status = dspio_scp(codec, MASTERCONTROL, MASTERCONTROL_ALLOC_DMA_CHAN,
  519. - SCP_GET, NULL, 0, dma_chan, &size);
  520. + status = dspio_scp(codec, MASTERCONTROL, 0x20,
  521. + MASTERCONTROL_ALLOC_DMA_CHAN, SCP_GET, NULL, 0, dma_chan,
  522. + &size);
  523. if (status < 0) {
  524. codec_dbg(codec, "dspio_alloc_dma_chan: SCP Failed\n");
  525. @@ -1552,8 +1918,9 @@
  526. codec_dbg(codec, " dspio_free_dma_chan() -- begin\n");
  527. codec_dbg(codec, "dspio_free_dma_chan: chan=%d\n", dma_chan);
  528. - status = dspio_scp(codec, MASTERCONTROL, MASTERCONTROL_ALLOC_DMA_CHAN,
  529. - SCP_SET, &dma_chan, sizeof(dma_chan), NULL, &dummy);
  530. + status = dspio_scp(codec, MASTERCONTROL, 0x20,
  531. + MASTERCONTROL_ALLOC_DMA_CHAN, SCP_SET, &dma_chan,
  532. + sizeof(dma_chan), NULL, &dummy);
  533. if (status < 0) {
  534. codec_dbg(codec, "dspio_free_dma_chan: SCP Failed\n");
  535. @@ -2575,14 +2942,16 @@
  536. */
  537. static void dspload_post_setup(struct hda_codec *codec)
  538. {
  539. + struct ca0132_spec *spec = codec->spec;
  540. codec_dbg(codec, "---- dspload_post_setup ------\n");
  541. + if (!spec->use_alt_functions) {
  542. + /*set DSP speaker to 2.0 configuration*/
  543. + chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x18), 0x08080080);
  544. + chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x19), 0x3f800000);
  545. - /*set DSP speaker to 2.0 configuration*/
  546. - chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x18), 0x08080080);
  547. - chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x19), 0x3f800000);
  548. -
  549. - /*update write pointer*/
  550. - chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x29), 0x00000002);
  551. + /*update write pointer*/
  552. + chipio_write(codec, XRAM_XRAM_INST_OFFSET(0x29), 0x00000002);
  553. + }
  554. }
  555. /**
  556. @@ -2690,6 +3059,169 @@
  557. }
  558. /*
  559. + * Setup GPIO for the other variants of Core3D.
  560. + */
  561. +
  562. +/*
  563. + * Sets up the GPIO pins so that they are discoverable. If this isn't done,
  564. + * the card shows as having no GPIO pins.
  565. + */
  566. +static void ca0132_gpio_init(struct hda_codec *codec)
  567. +{
  568. + struct ca0132_spec *spec = codec->spec;
  569. + switch (spec->quirk) {
  570. + case QUIRK_SBZ:
  571. + codec_dbg(codec, "SBZ ca0132_gpio_init");
  572. + snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
  573. + snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x53);
  574. + snd_hda_codec_write(codec, 0x01, 0, 0x790, 0x23);
  575. + break;
  576. + case QUIRK_R3DI:
  577. + codec_dbg(codec, "R3DI ca0132_gpio_init");
  578. + snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
  579. + snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x5B);
  580. + break;
  581. + }
  582. +
  583. +}
  584. +
  585. +/* Sets the GPIO for audio output. */
  586. +static void ca0132_gpio_setup(struct hda_codec *codec)
  587. +{
  588. + struct ca0132_spec *spec = codec->spec;
  589. + switch (spec->quirk) {
  590. + case QUIRK_SBZ:
  591. + snd_hda_codec_write(codec, 0x01, 0,
  592. + AC_VERB_SET_GPIO_DIRECTION, 0x07);
  593. + snd_hda_codec_write(codec, 0x01, 0,
  594. + AC_VERB_SET_GPIO_MASK, 0x07);
  595. + snd_hda_codec_write(codec, 0x01, 0,
  596. + AC_VERB_SET_GPIO_DATA, 0x04);
  597. + snd_hda_codec_write(codec, 0x01, 0,
  598. + AC_VERB_SET_GPIO_DATA, 0x06);
  599. + break;
  600. + case QUIRK_R3DI:
  601. + snd_hda_codec_write(codec, 0x01, 0,
  602. + AC_VERB_SET_GPIO_DIRECTION, 0x1E);
  603. + snd_hda_codec_write(codec, 0x01, 0,
  604. + AC_VERB_SET_GPIO_MASK, 0x1F);
  605. + snd_hda_codec_write(codec, 0x01, 0,
  606. + AC_VERB_SET_GPIO_DATA, 0x0C);
  607. + break;
  608. + }
  609. +}
  610. +
  611. +/*
  612. + * GPIO control functions for the Recon3D integrated.
  613. + */
  614. +
  615. +enum r3di_gpio_bit{
  616. + /* Bit 1 - Switch between front/rear mic. 0 = rear, 1 = front */
  617. + R3DI_MIC_SELECT_BIT = 1,
  618. + /* Bit 2 - Switch between headphone/line out. 0 = Headphone, 1 = Line */
  619. + R3DI_OUT_SELECT_BIT = 2,
  620. + /*
  621. + * I dunno what this actually does, but it stays on until the dsp
  622. + * is downloaded.
  623. + */
  624. + R3DI_GPIO_DSP_DOWNLOADING = 3,
  625. + /*
  626. + * Same as above, no clue what it does, but it comes on after the dsp
  627. + * is downloaded.
  628. + */
  629. + R3DI_GPIO_DSP_DOWNLOADED = 4
  630. +};
  631. +
  632. +enum r3di_mic_select {
  633. + /* Set GPIO bit 1 to 0 for rear mic */
  634. + R3DI_REAR_MIC = 0,
  635. + /* Set GPIO bit 1 to 1 for front microphone*/
  636. + R3DI_FRONT_MIC = 1
  637. +};
  638. +
  639. +enum r3di_out_select {
  640. + /* Set GPIO bit 2 to 0 for headphone */
  641. + R3DI_HEADPHONE_OUT = 0,
  642. + /* Set GPIO bit 2 to 1 for speaker */
  643. + R3DI_LINE_OUT = 1
  644. +};
  645. +enum r3di_dsp_status {
  646. + /* Set GPIO bit 3 to 1 until DSP is downloaded */
  647. + R3DI_DSP_DOWNLOADING = 0,
  648. + /* Set GPIO bit 4 to 1 once DSP is downloaded */
  649. + R3DI_DSP_DOWNLOADED = 1
  650. +};
  651. +
  652. +static void r3di_gpio_mic_set(struct hda_codec *codec,
  653. + enum r3di_mic_select cur_mic)
  654. +{
  655. + unsigned int cur_gpio;
  656. +
  657. + /* Get the current GPIO Data setup */
  658. + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0);
  659. +
  660. + switch (cur_mic) {
  661. + case R3DI_REAR_MIC:
  662. + cur_gpio &= ~(1 << R3DI_MIC_SELECT_BIT);
  663. + break;
  664. + case R3DI_FRONT_MIC:
  665. + cur_gpio |= (1 << R3DI_MIC_SELECT_BIT);
  666. + break;
  667. + }
  668. + snd_hda_codec_write(codec, codec->core.afg, 0,
  669. + AC_VERB_SET_GPIO_DATA, cur_gpio);
  670. +}
  671. +
  672. +static void r3di_gpio_out_set(struct hda_codec *codec,
  673. + enum r3di_out_select cur_out)
  674. +{
  675. + unsigned int cur_gpio;
  676. +
  677. + /* Get the current GPIO Data setup */
  678. + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0);
  679. +
  680. + switch (cur_out) {
  681. + case R3DI_HEADPHONE_OUT:
  682. + cur_gpio &= ~(1 << R3DI_OUT_SELECT_BIT);
  683. + break;
  684. + case R3DI_LINE_OUT:
  685. + cur_gpio |= (1 << R3DI_OUT_SELECT_BIT);
  686. + break;
  687. + }
  688. + snd_hda_codec_write(codec, codec->core.afg, 0,
  689. + AC_VERB_SET_GPIO_DATA, cur_gpio);
  690. +}
  691. +
  692. +static void r3di_gpio_dsp_status_set(struct hda_codec *codec,
  693. + enum r3di_dsp_status dsp_status)
  694. +{
  695. + unsigned int cur_gpio;
  696. +
  697. + /* Get the current GPIO Data setup */
  698. + cur_gpio = snd_hda_codec_read(codec, 0x01, 0, AC_VERB_GET_GPIO_DATA, 0);
  699. +
  700. + switch (dsp_status) {
  701. + case R3DI_DSP_DOWNLOADING:
  702. + cur_gpio |= (1 << R3DI_GPIO_DSP_DOWNLOADING);
  703. + snd_hda_codec_write(codec, codec->core.afg, 0,
  704. + AC_VERB_SET_GPIO_DATA, cur_gpio);
  705. + break;
  706. + case R3DI_DSP_DOWNLOADED:
  707. + /* Set DOWNLOADING bit to 0. */
  708. + cur_gpio &= ~(1 << R3DI_GPIO_DSP_DOWNLOADING);
  709. +
  710. + snd_hda_codec_write(codec, codec->core.afg, 0,
  711. + AC_VERB_SET_GPIO_DATA, cur_gpio);
  712. +
  713. + cur_gpio |= (1 << R3DI_GPIO_DSP_DOWNLOADED);
  714. + break;
  715. + }
  716. +
  717. + snd_hda_codec_write(codec, codec->core.afg, 0,
  718. + AC_VERB_SET_GPIO_DATA, cur_gpio);
  719. +}
  720. +
  721. +/*
  722. * PCM callbacks
  723. */
  724. static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
  725. @@ -2852,6 +3384,19 @@
  726. .tlv = { .c = ca0132_volume_tlv }, \
  727. .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) }
  728. +#define CA0132_ALT_CODEC_VOL_MONO(xname, nid, channel, dir) \
  729. + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  730. + .name = xname, \
  731. + .subdevice = HDA_SUBDEV_AMP_FLAG, \
  732. + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
  733. + SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
  734. + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
  735. + .info = snd_hda_mixer_amp_volume_info, \
  736. + .get = snd_hda_mixer_amp_volume_get, \
  737. + .put = ca0132_alt_volume_put, \
  738. + .tlv = { .c = snd_hda_mixer_amp_tlv }, \
  739. + .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, 0, dir) }
  740. +
  741. #define CA0132_CODEC_MUTE_MONO(xname, nid, channel, dir) \
  742. { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
  743. .name = xname, \
  744. @@ -2864,9 +3409,88 @@
  745. /* stereo */
  746. #define CA0132_CODEC_VOL(xname, nid, dir) \
  747. CA0132_CODEC_VOL_MONO(xname, nid, 3, dir)
  748. +#define CA0132_ALT_CODEC_VOL(xname, nid, dir) \
  749. + CA0132_ALT_CODEC_VOL_MONO(xname, nid, 3, dir)
  750. #define CA0132_CODEC_MUTE(xname, nid, dir) \
  751. CA0132_CODEC_MUTE_MONO(xname, nid, 3, dir)
  752. +/* lookup tables */
  753. +/*
  754. + * Lookup table with decibel values for the DSP. When volume is changed in
  755. + * Windows, the DSP is also sent the dB value in floating point. In Windows,
  756. + * these values have decimal points, probably because the Windows driver
  757. + * actually uses floating point. We can't here, so I made a lookup table of
  758. + * values -90 to 9. -90 is the lowest decibel value for both the ADC's and the
  759. + * DAC's, and 9 is the maximum.
  760. + */
  761. +static const unsigned int float_vol_db_lookup[] = {
  762. +0xC2B40000, 0xC2B20000, 0xC2B00000, 0xC2AE0000, 0xC2AC0000, 0xC2AA0000,
  763. +0xC2A80000, 0xC2A60000, 0xC2A40000, 0xC2A20000, 0xC2A00000, 0xC29E0000,
  764. +0xC29C0000, 0xC29A0000, 0xC2980000, 0xC2960000, 0xC2940000, 0xC2920000,
  765. +0xC2900000, 0xC28E0000, 0xC28C0000, 0xC28A0000, 0xC2880000, 0xC2860000,
  766. +0xC2840000, 0xC2820000, 0xC2800000, 0xC27C0000, 0xC2780000, 0xC2740000,
  767. +0xC2700000, 0xC26C0000, 0xC2680000, 0xC2640000, 0xC2600000, 0xC25C0000,
  768. +0xC2580000, 0xC2540000, 0xC2500000, 0xC24C0000, 0xC2480000, 0xC2440000,
  769. +0xC2400000, 0xC23C0000, 0xC2380000, 0xC2340000, 0xC2300000, 0xC22C0000,
  770. +0xC2280000, 0xC2240000, 0xC2200000, 0xC21C0000, 0xC2180000, 0xC2140000,
  771. +0xC2100000, 0xC20C0000, 0xC2080000, 0xC2040000, 0xC2000000, 0xC1F80000,
  772. +0xC1F00000, 0xC1E80000, 0xC1E00000, 0xC1D80000, 0xC1D00000, 0xC1C80000,
  773. +0xC1C00000, 0xC1B80000, 0xC1B00000, 0xC1A80000, 0xC1A00000, 0xC1980000,
  774. +0xC1900000, 0xC1880000, 0xC1800000, 0xC1700000, 0xC1600000, 0xC1500000,
  775. +0xC1400000, 0xC1300000, 0xC1200000, 0xC1100000, 0xC1000000, 0xC0E00000,
  776. +0xC0C00000, 0xC0A00000, 0xC0800000, 0xC0400000, 0xC0000000, 0xBF800000,
  777. +0x00000000, 0x3F800000, 0x40000000, 0x40400000, 0x40800000, 0x40A00000,
  778. +0x40C00000, 0x40E00000, 0x41000000, 0x41100000
  779. +};
  780. +
  781. +/*
  782. + * This table counts from float 0 to 1 in increments of .01, which is
  783. + * useful for a few different sliders.
  784. + */
  785. +static const unsigned int float_zero_to_one_lookup[] = {
  786. +0x00000000, 0x3C23D70A, 0x3CA3D70A, 0x3CF5C28F, 0x3D23D70A, 0x3D4CCCCD,
  787. +0x3D75C28F, 0x3D8F5C29, 0x3DA3D70A, 0x3DB851EC, 0x3DCCCCCD, 0x3DE147AE,
  788. +0x3DF5C28F, 0x3E051EB8, 0x3E0F5C29, 0x3E19999A, 0x3E23D70A, 0x3E2E147B,
  789. +0x3E3851EC, 0x3E428F5C, 0x3E4CCCCD, 0x3E570A3D, 0x3E6147AE, 0x3E6B851F,
  790. +0x3E75C28F, 0x3E800000, 0x3E851EB8, 0x3E8A3D71, 0x3E8F5C29, 0x3E947AE1,
  791. +0x3E99999A, 0x3E9EB852, 0x3EA3D70A, 0x3EA8F5C3, 0x3EAE147B, 0x3EB33333,
  792. +0x3EB851EC, 0x3EBD70A4, 0x3EC28F5C, 0x3EC7AE14, 0x3ECCCCCD, 0x3ED1EB85,
  793. +0x3ED70A3D, 0x3EDC28F6, 0x3EE147AE, 0x3EE66666, 0x3EEB851F, 0x3EF0A3D7,
  794. +0x3EF5C28F, 0x3EFAE148, 0x3F000000, 0x3F028F5C, 0x3F051EB8, 0x3F07AE14,
  795. +0x3F0A3D71, 0x3F0CCCCD, 0x3F0F5C29, 0x3F11EB85, 0x3F147AE1, 0x3F170A3D,
  796. +0x3F19999A, 0x3F1C28F6, 0x3F1EB852, 0x3F2147AE, 0x3F23D70A, 0x3F266666,
  797. +0x3F28F5C3, 0x3F2B851F, 0x3F2E147B, 0x3F30A3D7, 0x3F333333, 0x3F35C28F,
  798. +0x3F3851EC, 0x3F3AE148, 0x3F3D70A4, 0x3F400000, 0x3F428F5C, 0x3F451EB8,
  799. +0x3F47AE14, 0x3F4A3D71, 0x3F4CCCCD, 0x3F4F5C29, 0x3F51EB85, 0x3F547AE1,
  800. +0x3F570A3D, 0x3F59999A, 0x3F5C28F6, 0x3F5EB852, 0x3F6147AE, 0x3F63D70A,
  801. +0x3F666666, 0x3F68F5C3, 0x3F6B851F, 0x3F6E147B, 0x3F70A3D7, 0x3F733333,
  802. +0x3F75C28F, 0x3F7851EC, 0x3F7AE148, 0x3F7D70A4, 0x3F800000
  803. +};
  804. +
  805. +/*
  806. + * This table counts from float 10 to 1000, which is the range of the x-bass
  807. + * crossover slider in Windows.
  808. + */
  809. +static const unsigned int float_xbass_xover_lookup[] = {
  810. +0x41200000, 0x41A00000, 0x41F00000, 0x42200000, 0x42480000, 0x42700000,
  811. +0x428C0000, 0x42A00000, 0x42B40000, 0x42C80000, 0x42DC0000, 0x42F00000,
  812. +0x43020000, 0x430C0000, 0x43160000, 0x43200000, 0x432A0000, 0x43340000,
  813. +0x433E0000, 0x43480000, 0x43520000, 0x435C0000, 0x43660000, 0x43700000,
  814. +0x437A0000, 0x43820000, 0x43870000, 0x438C0000, 0x43910000, 0x43960000,
  815. +0x439B0000, 0x43A00000, 0x43A50000, 0x43AA0000, 0x43AF0000, 0x43B40000,
  816. +0x43B90000, 0x43BE0000, 0x43C30000, 0x43C80000, 0x43CD0000, 0x43D20000,
  817. +0x43D70000, 0x43DC0000, 0x43E10000, 0x43E60000, 0x43EB0000, 0x43F00000,
  818. +0x43F50000, 0x43FA0000, 0x43FF0000, 0x44020000, 0x44048000, 0x44070000,
  819. +0x44098000, 0x440C0000, 0x440E8000, 0x44110000, 0x44138000, 0x44160000,
  820. +0x44188000, 0x441B0000, 0x441D8000, 0x44200000, 0x44228000, 0x44250000,
  821. +0x44278000, 0x442A0000, 0x442C8000, 0x442F0000, 0x44318000, 0x44340000,
  822. +0x44368000, 0x44390000, 0x443B8000, 0x443E0000, 0x44408000, 0x44430000,
  823. +0x44458000, 0x44480000, 0x444A8000, 0x444D0000, 0x444F8000, 0x44520000,
  824. +0x44548000, 0x44570000, 0x44598000, 0x445C0000, 0x445E8000, 0x44610000,
  825. +0x44638000, 0x44660000, 0x44688000, 0x446B0000, 0x446D8000, 0x44700000,
  826. +0x44728000, 0x44750000, 0x44778000, 0x447A0000
  827. +};
  828. +
  829. /* The following are for tuning of products */
  830. #ifdef ENABLE_TUNING_CONTROLS
  831. @@ -2942,7 +3566,7 @@
  832. break;
  833. snd_hda_power_up(codec);
  834. - dspio_set_param(codec, ca0132_tuning_ctls[i].mid,
  835. + dspio_set_param(codec, ca0132_tuning_ctls[i].mid, 0x20,
  836. ca0132_tuning_ctls[i].req,
  837. &(lookup[idx]), sizeof(unsigned int));
  838. snd_hda_power_down(codec);
  839. @@ -3251,13 +3875,206 @@
  840. return err < 0 ? err : 0;
  841. }
  842. +/*
  843. + * This function behaves similarly to the ca0132_select_out funciton above,
  844. + * except with a few differences. It adds the ability to select the current
  845. + * output with an enumerated control "output source" if the auto detect
  846. + * mute switch is set to off. If the auto detect mute switch is enabled, it
  847. + * will detect either headphone or lineout(SPEAKER_OUT) from jack detection.
  848. + * It also adds the ability to auto-detect the front headphone port. The only
  849. + * way to select surround is to disable auto detect, and set Surround with the
  850. + * enumerated control.
  851. + */
  852. +static int ca0132_alt_select_out(struct hda_codec *codec)
  853. +{
  854. + struct ca0132_spec *spec = codec->spec;
  855. + unsigned int pin_ctl;
  856. + int jack_present;
  857. + int auto_jack;
  858. + unsigned int i;
  859. + unsigned int tmp;
  860. + int err;
  861. + /* Default Headphone is rear headphone */
  862. + hda_nid_t headphone_nid = spec->out_pins[1];
  863. +
  864. + codec_dbg(codec, "ca0132_alt_select_out\n");
  865. +
  866. + snd_hda_power_up_pm(codec);
  867. +
  868. + auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
  869. +
  870. + /* If headphone rear or front is plugged in, set to headphone.
  871. + * If neither is plugged in, set to rear line out. Only if
  872. + * hp/speaker auto detect is enabled. */
  873. + if (auto_jack) {
  874. + jack_present = snd_hda_jack_detect(codec, spec->unsol_tag_hp) ||
  875. + snd_hda_jack_detect(codec, spec->unsol_tag_front_hp);
  876. +
  877. + if (jack_present)
  878. + spec->cur_out_type = HEADPHONE_OUT;
  879. + else
  880. + spec->cur_out_type = SPEAKER_OUT;
  881. + } else
  882. + spec->cur_out_type = spec->out_enum_val;
  883. +
  884. + /* Begin DSP output switch */
  885. + tmp = FLOAT_ONE;
  886. + err = dspio_set_uint_param(codec, 0x96, 0x3A, tmp);
  887. + if (err < 0)
  888. + goto exit;
  889. +
  890. + switch (spec->cur_out_type) {
  891. + case SPEAKER_OUT:
  892. + codec_dbg(codec, "ca0132_alt_select_out speaker\n");
  893. + /*speaker out config*/
  894. + switch (spec->quirk) {
  895. + case QUIRK_SBZ:
  896. + writew(0x0007, spec->mem_base + 0x320);
  897. + writew(0x0104, spec->mem_base + 0x320);
  898. + writew(0x0101, spec->mem_base + 0x320);
  899. + chipio_set_control_param(codec, 0x0D, 0x18);
  900. + break;
  901. + case QUIRK_R3DI:
  902. + chipio_set_control_param(codec, 0x0D, 0x24);
  903. + r3di_gpio_out_set(codec, R3DI_LINE_OUT);
  904. + break;
  905. + }
  906. +
  907. + /* disable headphone node */
  908. + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0,
  909. + AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  910. + snd_hda_set_pin_ctl(codec, spec->out_pins[1],
  911. + pin_ctl & ~PIN_HP);
  912. + /* enable line-out node */
  913. + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
  914. + AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  915. + snd_hda_set_pin_ctl(codec, spec->out_pins[0],
  916. + pin_ctl | PIN_OUT);
  917. + /* Enable EAPD */
  918. + snd_hda_codec_write(codec, spec->out_pins[0], 0,
  919. + AC_VERB_SET_EAPD_BTLENABLE, 0x01);
  920. +
  921. + /* If PlayEnhancement is enabled, set different source */
  922. + if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID])
  923. + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ONE);
  924. + else
  925. + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_EIGHT);
  926. + break;
  927. + case HEADPHONE_OUT:
  928. + codec_dbg(codec, "ca0132_alt_select_out hp\n");
  929. + /* Headphone out config*/
  930. + switch (spec->quirk) {
  931. + case QUIRK_SBZ:
  932. + writew(0x0107, spec->mem_base + 0x320);
  933. + writew(0x0104, spec->mem_base + 0x320);
  934. + writew(0x0001, spec->mem_base + 0x320);
  935. + chipio_set_control_param(codec, 0x0D, 0x12);
  936. + break;
  937. + case QUIRK_R3DI:
  938. + chipio_set_control_param(codec, 0x0D, 0x21);
  939. + r3di_gpio_out_set(codec, R3DI_HEADPHONE_OUT);
  940. + break;
  941. + }
  942. +
  943. + snd_hda_codec_write(codec, spec->out_pins[0], 0,
  944. + AC_VERB_SET_EAPD_BTLENABLE, 0x00);
  945. +
  946. + /* disable speaker*/
  947. + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
  948. + AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  949. + snd_hda_set_pin_ctl(codec, spec->out_pins[0], pin_ctl & ~PIN_HP);
  950. +
  951. + /* enable headphone, either front or rear */
  952. +
  953. + if (snd_hda_jack_detect(codec, spec->unsol_tag_front_hp))
  954. + headphone_nid = spec->out_pins[2];
  955. + else if (snd_hda_jack_detect(codec, spec->unsol_tag_hp))
  956. + headphone_nid = spec->out_pins[1];
  957. +
  958. + pin_ctl = snd_hda_codec_read(codec, headphone_nid, 0,
  959. + AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  960. + snd_hda_set_pin_ctl(codec, headphone_nid,
  961. + pin_ctl | PIN_HP);
  962. +
  963. + if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID])
  964. + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ONE);
  965. + else
  966. + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ZERO);
  967. + break;
  968. + case SURROUND_OUT:
  969. + codec_dbg(codec, "ca0132_alt_select_out Surround\n");
  970. + /* Surround out config*/
  971. + switch (spec->quirk) {
  972. + case QUIRK_SBZ:
  973. + writew(0x0007, spec->mem_base + 0x320);
  974. + writew(0x0104, spec->mem_base + 0x320);
  975. + writew(0x0101, spec->mem_base + 0x320);
  976. + chipio_set_control_param(codec, 0x0D, 0x18);
  977. + break;
  978. + case QUIRK_R3DI:
  979. + chipio_set_control_param(codec, 0x0D, 0x24);
  980. + r3di_gpio_out_set(codec, R3DI_LINE_OUT);
  981. + break;
  982. + }
  983. + /* enable line out node */
  984. + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
  985. + AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  986. + snd_hda_set_pin_ctl(codec, spec->out_pins[0],
  987. + pin_ctl | PIN_OUT);
  988. + /* Disable headphone out */
  989. + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[1], 0,
  990. + AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  991. + snd_hda_set_pin_ctl(codec, spec->out_pins[1],
  992. + pin_ctl & ~PIN_HP);
  993. + /* Enable EAPD on line out */
  994. + snd_hda_codec_write(codec, spec->out_pins[0], 0,
  995. + AC_VERB_SET_EAPD_BTLENABLE, 0x01);
  996. + /* enable center/lfe out node */
  997. + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[2], 0,
  998. + AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  999. + snd_hda_set_pin_ctl(codec, spec->out_pins[2],
  1000. + pin_ctl | PIN_OUT);
  1001. + /* Now set rear surround node as out. */
  1002. + pin_ctl = snd_hda_codec_read(codec, spec->out_pins[3], 0,
  1003. + AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
  1004. + snd_hda_set_pin_ctl(codec, spec->out_pins[3],
  1005. + pin_ctl | PIN_OUT);
  1006. +
  1007. + if (spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID])
  1008. + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_ONE);
  1009. + else
  1010. + dspio_set_uint_param(codec, 0x80, 0x04, FLOAT_EIGHT);
  1011. + break;
  1012. + }
  1013. +
  1014. + /* run through the output dsp commands for line-out */
  1015. + for(i = 0; i < alt_out_presets[spec->cur_out_type].commands; i++) {
  1016. + err = dspio_set_uint_param(codec,
  1017. + alt_out_presets[spec->cur_out_type].mids[i],
  1018. + alt_out_presets[spec->cur_out_type].reqs[i],
  1019. + alt_out_presets[spec->cur_out_type].vals[i]);
  1020. +
  1021. + if (err < 0)
  1022. + goto exit;
  1023. + }
  1024. +
  1025. +exit:
  1026. + snd_hda_power_down_pm(codec);
  1027. +
  1028. + return err < 0 ? err : 0;
  1029. +}
  1030. +
  1031. static void ca0132_unsol_hp_delayed(struct work_struct *work)
  1032. {
  1033. struct ca0132_spec *spec = container_of(
  1034. to_delayed_work(work), struct ca0132_spec, unsol_hp_work);
  1035. struct hda_jack_tbl *jack;
  1036. - ca0132_select_out(spec->codec);
  1037. + if(spec->use_alt_functions)
  1038. + ca0132_alt_select_out(spec->codec);
  1039. + else
  1040. + ca0132_select_out(spec->codec);
  1041. +
  1042. jack = snd_hda_jack_tbl_get(spec->codec, spec->unsol_tag_hp);
  1043. if (jack) {
  1044. jack->block_report = 0;
  1045. @@ -3268,6 +4085,10 @@
  1046. static void ca0132_set_dmic(struct hda_codec *codec, int enable);
  1047. static int ca0132_mic_boost_set(struct hda_codec *codec, long val);
  1048. static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val);
  1049. +static void resume_mic1(struct hda_codec *codec, unsigned int oldval);
  1050. +static int stop_mic1(struct hda_codec *codec);
  1051. +static int ca0132_cvoice_switch_set(struct hda_codec *codec);
  1052. +static int ca0132_alt_mic_boost_set(struct hda_codec *codec, long val);
  1053. /*
  1054. * Select the active VIP source
  1055. @@ -3310,6 +4131,71 @@
  1056. return 1;
  1057. }
  1058. +static int ca0132_alt_set_vipsource(struct hda_codec *codec, int val)
  1059. +{
  1060. + struct ca0132_spec *spec = codec->spec;
  1061. + unsigned int tmp;
  1062. +
  1063. + if (spec->dsp_state != DSP_DOWNLOADED)
  1064. + return 0;
  1065. +
  1066. + codec_dbg(codec, "ca0132_alt_set_vipsource");
  1067. +
  1068. + chipio_set_stream_control(codec, 0x03, 0);
  1069. + chipio_set_stream_control(codec, 0x04, 0);
  1070. +
  1071. + /* if CrystalVoice is off, vipsource should be 0 */
  1072. + if (!spec->effects_switch[CRYSTAL_VOICE - EFFECT_START_NID] ||
  1073. + (val == 0) || spec->in_enum_val == REAR_LINE_IN) {
  1074. + codec_dbg(codec, "ca0132_alt_set_vipsource off.");
  1075. + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0);
  1076. +
  1077. + tmp = FLOAT_ZERO;
  1078. + dspio_set_uint_param(codec, 0x80, 0x05, tmp);
  1079. +
  1080. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
  1081. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
  1082. + if (spec->quirk == QUIRK_R3DI)
  1083. + chipio_set_conn_rate(codec, 0x0F, SR_96_000);
  1084. +
  1085. +
  1086. + if (spec->in_enum_val == REAR_LINE_IN)
  1087. + tmp = FLOAT_ZERO;
  1088. + else {
  1089. + if (spec->quirk == QUIRK_SBZ)
  1090. + tmp = FLOAT_THREE;
  1091. + else
  1092. + tmp = FLOAT_ONE;
  1093. + }
  1094. +
  1095. + dspio_set_uint_param(codec, 0x80, 0x00, tmp);
  1096. +
  1097. + } else {
  1098. + codec_dbg(codec, "ca0132_alt_set_vipsource on.");
  1099. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_16_000);
  1100. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_16_000);
  1101. + if (spec->quirk == QUIRK_R3DI)
  1102. + chipio_set_conn_rate(codec, 0x0F, SR_16_000);
  1103. +
  1104. + if (spec->effects_switch[VOICE_FOCUS - EFFECT_START_NID])
  1105. + tmp = FLOAT_TWO;
  1106. + else
  1107. + tmp = FLOAT_ONE;
  1108. + dspio_set_uint_param(codec, 0x80, 0x00, tmp);
  1109. +
  1110. + tmp = FLOAT_ONE;
  1111. + dspio_set_uint_param(codec, 0x80, 0x05, tmp);
  1112. +
  1113. + msleep(20);
  1114. + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, val);
  1115. + }
  1116. +
  1117. + chipio_set_stream_control(codec, 0x03, 1);
  1118. + chipio_set_stream_control(codec, 0x04, 1);
  1119. +
  1120. + return 1;
  1121. +}
  1122. +
  1123. /*
  1124. * Select the active microphone.
  1125. * If autodetect is enabled, mic will be selected based on jack detection.
  1126. @@ -3363,6 +4249,126 @@
  1127. }
  1128. /*
  1129. + * Select the active input.
  1130. + * Mic detection isn't used, because it's kind of pointless on the SBZ.
  1131. + * The front mic has no jack-detection, so the only way to switch to it
  1132. + * is to do it manually in alsamixer.
  1133. + */
  1134. +
  1135. +static int ca0132_alt_select_in(struct hda_codec *codec)
  1136. +{
  1137. + struct ca0132_spec *spec = codec->spec;
  1138. + unsigned int tmp;
  1139. +
  1140. + codec_dbg(codec, "ca0132_alt_select_in\n");
  1141. +
  1142. + snd_hda_power_up_pm(codec);
  1143. +
  1144. + chipio_set_stream_control(codec, 0x03, 0);
  1145. + chipio_set_stream_control(codec, 0x04, 0);
  1146. +
  1147. + spec->cur_mic_type = spec->in_enum_val;
  1148. +
  1149. + switch (spec->cur_mic_type) {
  1150. + case REAR_MIC:
  1151. + switch (spec->quirk) {
  1152. + case QUIRK_SBZ:
  1153. + writew(0x0000, spec->mem_base + 0x320);
  1154. + tmp = FLOAT_THREE;
  1155. + break;
  1156. + case QUIRK_R3DI:
  1157. + r3di_gpio_mic_set(codec, R3DI_REAR_MIC);
  1158. + tmp = FLOAT_ONE;
  1159. + break;
  1160. + default:
  1161. + tmp = FLOAT_ONE;
  1162. + break;
  1163. + }
  1164. +
  1165. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
  1166. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
  1167. + if (spec->quirk == QUIRK_R3DI)
  1168. + chipio_set_conn_rate(codec, 0x0F, SR_96_000);
  1169. +
  1170. + dspio_set_uint_param(codec, 0x80, 0x00, tmp);
  1171. +
  1172. + chipio_set_stream_control(codec, 0x03, 1);
  1173. + chipio_set_stream_control(codec, 0x04, 1);
  1174. +
  1175. + if (spec->quirk == QUIRK_SBZ) {
  1176. + chipio_write(codec, 0x18B098, 0x0000000C);
  1177. + chipio_write(codec, 0x18B09C, 0x0000000C);
  1178. + }
  1179. + ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val);
  1180. + break;
  1181. + case REAR_LINE_IN:
  1182. + ca0132_mic_boost_set(codec, 0);
  1183. + switch (spec->quirk) {
  1184. + case QUIRK_SBZ:
  1185. + writew(0x0000, spec->mem_base + 0x320);
  1186. + break;
  1187. + case QUIRK_R3DI:
  1188. + r3di_gpio_mic_set(codec, R3DI_REAR_MIC);
  1189. + break;
  1190. + }
  1191. +
  1192. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
  1193. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
  1194. + if (spec->quirk == QUIRK_R3DI)
  1195. + chipio_set_conn_rate(codec, 0x0F, SR_96_000);
  1196. +
  1197. + tmp = FLOAT_ZERO;
  1198. + dspio_set_uint_param(codec, 0x80, 0x00, tmp);
  1199. +
  1200. + if (spec->quirk == QUIRK_SBZ) {
  1201. + chipio_write(codec, 0x18B098, 0x00000000);
  1202. + chipio_write(codec, 0x18B09C, 0x00000000);
  1203. + }
  1204. +
  1205. + chipio_set_stream_control(codec, 0x03, 1);
  1206. + chipio_set_stream_control(codec, 0x04, 1);
  1207. + break;
  1208. + case FRONT_MIC:
  1209. + switch (spec->quirk) {
  1210. + case QUIRK_SBZ:
  1211. + writew(0x0100, spec->mem_base + 0x320);
  1212. + writew(0x0005, spec->mem_base + 0x320);
  1213. + tmp = FLOAT_THREE;
  1214. + break;
  1215. + case QUIRK_R3DI:
  1216. + r3di_gpio_mic_set(codec, R3DI_FRONT_MIC);
  1217. + tmp = FLOAT_ONE;
  1218. + break;
  1219. + default:
  1220. + tmp = FLOAT_ONE;
  1221. + break;
  1222. + }
  1223. +
  1224. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
  1225. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
  1226. + if (spec->quirk == QUIRK_R3DI)
  1227. + chipio_set_conn_rate(codec, 0x0F, SR_96_000);
  1228. +
  1229. + dspio_set_uint_param(codec, 0x80, 0x00, tmp);
  1230. +
  1231. + chipio_set_stream_control(codec, 0x03, 1);
  1232. + chipio_set_stream_control(codec, 0x04, 1);
  1233. +
  1234. + if (spec->quirk == QUIRK_SBZ) {
  1235. + chipio_write(codec, 0x18B098, 0x0000000C);
  1236. + chipio_write(codec, 0x18B09C, 0x000000CC);
  1237. + }
  1238. + ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val);
  1239. + break;
  1240. + }
  1241. + ca0132_cvoice_switch_set(codec);
  1242. +
  1243. + snd_hda_power_down_pm(codec);
  1244. + return 0;
  1245. +
  1246. +}
  1247. +
  1248. +/*
  1249. * Check if VNODE settings take effect immediately.
  1250. */
  1251. static bool ca0132_is_vnode_effective(struct hda_codec *codec,
  1252. @@ -3418,7 +4424,7 @@
  1253. static int ca0132_effects_set(struct hda_codec *codec, hda_nid_t nid, long val)
  1254. {
  1255. struct ca0132_spec *spec = codec->spec;
  1256. - unsigned int on;
  1257. + unsigned int on, tmp;
  1258. int num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
  1259. int err = 0;
  1260. int idx = nid - EFFECT_START_NID;
  1261. @@ -3442,6 +4448,45 @@
  1262. /* Voice Focus applies to 2-ch Mic, Digital Mic */
  1263. if ((nid == VOICE_FOCUS) && (spec->cur_mic_type != DIGITAL_MIC))
  1264. val = 0;
  1265. +
  1266. + /* If Voice Focus on SBZ, set to two channel. */
  1267. + if ((nid == VOICE_FOCUS) && (spec->quirk == QUIRK_SBZ)
  1268. + && (spec->cur_mic_type != REAR_LINE_IN)) {
  1269. + if (spec->effects_switch[CRYSTAL_VOICE -
  1270. + EFFECT_START_NID]) {
  1271. +
  1272. + if (spec->effects_switch[VOICE_FOCUS -
  1273. + EFFECT_START_NID])
  1274. + tmp = FLOAT_TWO;
  1275. + else
  1276. + tmp = FLOAT_ONE;
  1277. +
  1278. + dspio_set_uint_param(codec, 0x80, 0x00, tmp);
  1279. + }
  1280. + }
  1281. +
  1282. + /* For SBZ noise reduction, there's an extra command
  1283. + * to module ID 0x47. No clue why. */
  1284. + if ((nid == NOISE_REDUCTION) && (spec->quirk == QUIRK_SBZ)
  1285. + && (spec->cur_mic_type != REAR_LINE_IN)) {
  1286. + if (spec->effects_switch[CRYSTAL_VOICE -
  1287. + EFFECT_START_NID]) {
  1288. + if (spec->effects_switch[NOISE_REDUCTION -
  1289. + EFFECT_START_NID])
  1290. + tmp = FLOAT_ONE;
  1291. + else
  1292. + tmp = FLOAT_ZERO;
  1293. + }
  1294. + else
  1295. + tmp = FLOAT_ZERO;
  1296. +
  1297. + dspio_set_uint_param(codec, 0x47, 0x00, tmp);
  1298. + }
  1299. +
  1300. + /* If rear line in disable effects. */
  1301. + if (spec->use_alt_functions &&
  1302. + spec->in_enum_val == REAR_LINE_IN)
  1303. + val = 0;
  1304. }
  1305. codec_dbg(codec, "ca0132_effect_set: nid=0x%x, val=%ld\n",
  1306. @@ -3469,6 +4514,9 @@
  1307. codec_dbg(codec, "ca0132_pe_switch_set: val=%ld\n",
  1308. spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID]);
  1309. + if (spec->use_alt_functions)
  1310. + ca0132_alt_select_out(codec);
  1311. +
  1312. i = OUT_EFFECT_START_NID - EFFECT_START_NID;
  1313. nid = OUT_EFFECT_START_NID;
  1314. /* PE affects all out effects */
  1315. @@ -3526,7 +4574,10 @@
  1316. /* set correct vipsource */
  1317. oldval = stop_mic1(codec);
  1318. - ret |= ca0132_set_vipsource(codec, 1);
  1319. + if (spec->use_alt_functions)
  1320. + ret |= ca0132_alt_set_vipsource(codec, 1);
  1321. + else
  1322. + ret |= ca0132_set_vipsource(codec, 1);
  1323. resume_mic1(codec, oldval);
  1324. return ret;
  1325. }
  1326. @@ -3546,6 +4597,16 @@
  1327. return ret;
  1328. }
  1329. +static int ca0132_alt_mic_boost_set(struct hda_codec *codec, long val)
  1330. +{
  1331. + struct ca0132_spec *spec = codec->spec;
  1332. + int ret = 0;
  1333. +
  1334. + ret = snd_hda_codec_amp_update(codec, spec->input_pins[0], 0,
  1335. + HDA_INPUT, 0, HDA_AMP_VOLMASK, val);
  1336. + return ret;
  1337. +}
  1338. +
  1339. static int ca0132_vnode_switch_set(struct snd_kcontrol *kcontrol,
  1340. struct snd_ctl_elem_value *ucontrol)
  1341. {
  1342. @@ -3560,8 +4621,12 @@
  1343. if (nid == VNID_HP_SEL) {
  1344. auto_jack =
  1345. spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
  1346. - if (!auto_jack)
  1347. - ca0132_select_out(codec);
  1348. + if (!auto_jack) {
  1349. + if (spec->use_alt_functions)
  1350. + ca0132_alt_select_out(codec);
  1351. + else
  1352. + ca0132_select_out(codec);
  1353. + }
  1354. return 1;
  1355. }
  1356. @@ -3574,7 +4639,10 @@
  1357. }
  1358. if (nid == VNID_HP_ASEL) {
  1359. - ca0132_select_out(codec);
  1360. + if (spec->use_alt_functions)
  1361. + ca0132_alt_select_out(codec);
  1362. + else
  1363. + ca0132_select_out(codec);
  1364. return 1;
  1365. }
  1366. @@ -3602,6 +4670,428 @@
  1367. return ret;
  1368. }
  1369. /* End of control change helpers. */
  1370. +/*
  1371. + * Below I've added controls to mess with the effect levels, I've only enabled
  1372. + * them on the Sound Blaster Z, but they would probably also work on the
  1373. + * Chromebook. I figured they were probably tuned specifically for it, and left
  1374. + * out for a reason.
  1375. + */
  1376. +
  1377. +/* Sets DSP effect level from the sliders above the controls */
  1378. +static int ca0132_alt_slider_ctl_set(struct hda_codec *codec, hda_nid_t nid,
  1379. + const unsigned int *lookup, int idx)
  1380. +{
  1381. + int i = 0;
  1382. + unsigned int y;
  1383. + /* For X_BASS, req 2 is actually crossover freq instead of
  1384. + * effect level */
  1385. + if (nid == X_BASS)
  1386. + y = 2;
  1387. + else
  1388. + y = 1;
  1389. +
  1390. + snd_hda_power_up(codec);
  1391. + if (nid == XBASS_XOVER) {
  1392. + for(i = 0; i < OUT_EFFECTS_COUNT; i++)
  1393. + if (X_BASS == ca0132_effects[i].nid)
  1394. + break;
  1395. +
  1396. + dspio_set_param(codec, ca0132_effects[i].mid, 0x20,
  1397. + ca0132_effects[i].reqs[1],
  1398. + &(lookup[idx - 1]), sizeof(unsigned int));
  1399. + } else {
  1400. + /* Find the actual effect structure */
  1401. + for(i = 0; i < OUT_EFFECTS_COUNT; i++)
  1402. + if (nid == ca0132_effects[i].nid)
  1403. + break;
  1404. +
  1405. + dspio_set_param(codec, ca0132_effects[i].mid, 0x20,
  1406. + ca0132_effects[i].reqs[y],
  1407. + &(lookup[idx]), sizeof(unsigned int));
  1408. + }
  1409. +
  1410. + snd_hda_power_down(codec);
  1411. +
  1412. + return 0;
  1413. +}
  1414. +
  1415. +static int ca0132_alt_xbass_xover_slider_ctl_get(struct snd_kcontrol *kcontrol,
  1416. + struct snd_ctl_elem_value *ucontrol)
  1417. +{
  1418. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1419. + struct ca0132_spec *spec = codec->spec;
  1420. + long *valp = ucontrol->value.integer.value;
  1421. +
  1422. + *valp = spec->xbass_xover_freq;
  1423. + return 0;
  1424. +}
  1425. +
  1426. +static int ca0132_alt_slider_ctl_get(struct snd_kcontrol *kcontrol,
  1427. + struct snd_ctl_elem_value *ucontrol)
  1428. +{
  1429. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1430. + struct ca0132_spec *spec = codec->spec;
  1431. + hda_nid_t nid = get_amp_nid(kcontrol);
  1432. + long *valp = ucontrol->value.integer.value;
  1433. + int idx = nid - OUT_EFFECT_START_NID;
  1434. +
  1435. + *valp = spec->fx_ctl_val[idx];
  1436. + return 0;
  1437. +}
  1438. +
  1439. +/*
  1440. + * The X-bass crossover starts at 10hz, so the min is 1. The
  1441. + * frequency is set in multiples of 10.
  1442. + */
  1443. +static int ca0132_alt_xbass_xover_slider_info(struct snd_kcontrol *kcontrol,
  1444. + struct snd_ctl_elem_info *uinfo)
  1445. +{
  1446. + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  1447. + uinfo->count = 1;
  1448. + uinfo->value.integer.min = 1;
  1449. + uinfo->value.integer.max = 100;
  1450. + uinfo->value.integer.step = 1;
  1451. +
  1452. + return 0;
  1453. +}
  1454. +
  1455. +static int ca0132_alt_effect_slider_info(struct snd_kcontrol *kcontrol,
  1456. + struct snd_ctl_elem_info *uinfo)
  1457. +{
  1458. + int chs = get_amp_channels(kcontrol);
  1459. + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
  1460. + uinfo->count = chs == 3 ? 2 : 1;
  1461. + uinfo->value.integer.min = 0;
  1462. + uinfo->value.integer.max = 100;
  1463. + uinfo->value.integer.step = 1;
  1464. +
  1465. + return 0;
  1466. +}
  1467. +
  1468. +static int ca0132_alt_xbass_xover_slider_put(struct snd_kcontrol *kcontrol,
  1469. + struct snd_ctl_elem_value *ucontrol)
  1470. +{
  1471. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1472. + struct ca0132_spec *spec = codec->spec;
  1473. + hda_nid_t nid = get_amp_nid(kcontrol);
  1474. + long *valp = ucontrol->value.integer.value;
  1475. + int idx;
  1476. +
  1477. + /* any change? */
  1478. + if (spec->xbass_xover_freq == *valp)
  1479. + return 0;
  1480. +
  1481. + spec->xbass_xover_freq = *valp;
  1482. +
  1483. + idx = *valp;
  1484. + ca0132_alt_slider_ctl_set(codec, nid, float_xbass_xover_lookup, idx);
  1485. +
  1486. + return 0;
  1487. +}
  1488. +
  1489. +static int ca0132_alt_effect_slider_put(struct snd_kcontrol *kcontrol,
  1490. + struct snd_ctl_elem_value *ucontrol)
  1491. +{
  1492. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1493. + struct ca0132_spec *spec = codec->spec;
  1494. + hda_nid_t nid = get_amp_nid(kcontrol);
  1495. + long *valp = ucontrol->value.integer.value;
  1496. + int idx;
  1497. +
  1498. + idx = nid - EFFECT_START_NID;
  1499. + /* any change? */
  1500. + if (spec->fx_ctl_val[idx] == *valp)
  1501. + return 0;
  1502. +
  1503. + spec->fx_ctl_val[idx] = *valp;
  1504. +
  1505. + idx = *valp;
  1506. + ca0132_alt_slider_ctl_set(codec, nid, float_zero_to_one_lookup, idx);
  1507. +
  1508. + return 0;
  1509. +}
  1510. +
  1511. +
  1512. +/* Mic Boost Enum for alternative ca0132 codecs. I didn't like that the original
  1513. + * only has off or full 30 dB, and didn't like making a volume slider that has
  1514. + * traditional 0-100 in alsamixer that goes in big steps. I like enum better. */
  1515. +#define MIC_BOOST_NUM_OF_STEPS 4
  1516. +#define MIC_BOOST_ENUM_MAX_STRLEN 10
  1517. +
  1518. +static int ca0132_alt_mic_boost_info(struct snd_kcontrol *kcontrol,
  1519. + struct snd_ctl_elem_info *uinfo)
  1520. +{
  1521. + char *sfx = "dB";
  1522. + char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
  1523. + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  1524. + uinfo->count = 1;
  1525. + uinfo->value.enumerated.items = MIC_BOOST_NUM_OF_STEPS;
  1526. + if (uinfo->value.enumerated.item >= MIC_BOOST_NUM_OF_STEPS)
  1527. + uinfo->value.enumerated.item = MIC_BOOST_NUM_OF_STEPS - 1;
  1528. + sprintf(namestr, "%d %s", (uinfo->value.enumerated.item * 10), sfx);
  1529. + strcpy(uinfo->value.enumerated.name, namestr);
  1530. + return 0;
  1531. +}
  1532. +
  1533. +static int ca0132_alt_mic_boost_get(struct snd_kcontrol *kcontrol,
  1534. + struct snd_ctl_elem_value *ucontrol)
  1535. +{
  1536. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1537. + struct ca0132_spec *spec = codec->spec;
  1538. +
  1539. + ucontrol->value.enumerated.item[0] = spec->mic_boost_enum_val;
  1540. + return 0;
  1541. +}
  1542. +
  1543. +static int ca0132_alt_mic_boost_put(struct snd_kcontrol *kcontrol,
  1544. + struct snd_ctl_elem_value *ucontrol)
  1545. +{
  1546. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1547. + struct ca0132_spec *spec = codec->spec;
  1548. + int sel = ucontrol->value.enumerated.item[0];
  1549. + unsigned int items = MIC_BOOST_NUM_OF_STEPS;
  1550. +
  1551. + if (sel >= items)
  1552. + return 0;
  1553. +
  1554. + codec_dbg(codec, "ca0132_alt_mic_boost: boost=%d\n",
  1555. + sel);
  1556. +
  1557. + spec->mic_boost_enum_val = sel;
  1558. +
  1559. + if (spec->in_enum_val != REAR_LINE_IN)
  1560. + ca0132_alt_mic_boost_set(codec, spec->mic_boost_enum_val);
  1561. +
  1562. + return 1;
  1563. +}
  1564. +
  1565. +
  1566. +/* Input Select Control for alternative ca0132 codecs. This exists because
  1567. + * front microphone has no auto-detect, and we need a way to set the rear
  1568. + * as line-in */
  1569. +
  1570. +static int ca0132_alt_input_source_info(struct snd_kcontrol *kcontrol,
  1571. + struct snd_ctl_elem_info *uinfo)
  1572. +{
  1573. + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  1574. + uinfo->count = 1;
  1575. + uinfo->value.enumerated.items = IN_SRC_NUM_OF_INPUTS;
  1576. + if (uinfo->value.enumerated.item >= IN_SRC_NUM_OF_INPUTS)
  1577. + uinfo->value.enumerated.item = IN_SRC_NUM_OF_INPUTS - 1;
  1578. + strcpy(uinfo->value.enumerated.name,
  1579. + in_src_str[uinfo->value.enumerated.item]);
  1580. + return 0;
  1581. +}
  1582. +
  1583. +static int ca0132_alt_input_source_get(struct snd_kcontrol *kcontrol,
  1584. + struct snd_ctl_elem_value *ucontrol)
  1585. +{
  1586. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1587. + struct ca0132_spec *spec = codec->spec;
  1588. +
  1589. + ucontrol->value.enumerated.item[0] = spec->in_enum_val;
  1590. + return 0;
  1591. +}
  1592. +
  1593. +static int ca0132_alt_input_source_put(struct snd_kcontrol *kcontrol,
  1594. + struct snd_ctl_elem_value *ucontrol)
  1595. +{
  1596. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1597. + struct ca0132_spec *spec = codec->spec;
  1598. + int sel = ucontrol->value.enumerated.item[0];
  1599. + unsigned int items = IN_SRC_NUM_OF_INPUTS;
  1600. +
  1601. + if (sel >= items)
  1602. + return 0;
  1603. +
  1604. + codec_dbg(codec, "ca0132_alt_input_select: sel=%d, preset=%s\n",
  1605. + sel, in_src_str[sel]);
  1606. +
  1607. + spec->in_enum_val = sel;
  1608. +
  1609. + ca0132_alt_select_in(codec);
  1610. +
  1611. + return 1;
  1612. +}
  1613. +
  1614. +/* Sound Blaster Z Output Select Control */
  1615. +static int ca0132_alt_output_select_get_info(struct snd_kcontrol *kcontrol,
  1616. + struct snd_ctl_elem_info *uinfo)
  1617. +{
  1618. + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  1619. + uinfo->count = 1;
  1620. + uinfo->value.enumerated.items = NUM_OF_OUTPUTS;
  1621. + if (uinfo->value.enumerated.item >= NUM_OF_OUTPUTS)
  1622. + uinfo->value.enumerated.item = NUM_OF_OUTPUTS - 1;
  1623. + strcpy(uinfo->value.enumerated.name,
  1624. + alt_out_presets[uinfo->value.enumerated.item].name);
  1625. + return 0;
  1626. +}
  1627. +
  1628. +static int ca0132_alt_output_select_get(struct snd_kcontrol *kcontrol,
  1629. + struct snd_ctl_elem_value *ucontrol)
  1630. +{
  1631. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1632. + struct ca0132_spec *spec = codec->spec;
  1633. +
  1634. + ucontrol->value.enumerated.item[0] = spec->out_enum_val;
  1635. + return 0;
  1636. +}
  1637. +
  1638. +static int ca0132_alt_output_select_put(struct snd_kcontrol *kcontrol,
  1639. + struct snd_ctl_elem_value *ucontrol)
  1640. +{
  1641. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1642. + struct ca0132_spec *spec = codec->spec;
  1643. + int sel = ucontrol->value.enumerated.item[0];
  1644. + unsigned int items = NUM_OF_OUTPUTS;
  1645. + unsigned int auto_jack;
  1646. +
  1647. + if (sel >= items)
  1648. + return 0;
  1649. +
  1650. + codec_dbg(codec, "ca0132_alt_output_select: sel=%d, preset=%s\n",
  1651. + sel, alt_out_presets[sel].name);
  1652. +
  1653. + spec->out_enum_val = sel;
  1654. +
  1655. + auto_jack = spec->vnode_lswitch[VNID_HP_ASEL - VNODE_START_NID];
  1656. +
  1657. + if (!auto_jack) {
  1658. + ca0132_alt_select_out(codec);
  1659. + }
  1660. +
  1661. + return 1;
  1662. +}
  1663. +
  1664. +/* Smart Volume output setting control. Three different settings, Normal,
  1665. + * which takes the value from the smart volume slider. The two others, loud
  1666. + * and night, disregard the slider value and have uneditable values. */
  1667. +#define NUM_OF_SVM_SETTINGS 3
  1668. +static const char *out_svm_set_enum_str[3] = {"Normal", "Loud", "Night" };
  1669. +
  1670. +static int ca0132_alt_svm_setting_info(struct snd_kcontrol *kcontrol,
  1671. + struct snd_ctl_elem_info *uinfo)
  1672. +{
  1673. + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  1674. + uinfo->count = 1;
  1675. + uinfo->value.enumerated.items = NUM_OF_SVM_SETTINGS;
  1676. + if (uinfo->value.enumerated.item >= NUM_OF_SVM_SETTINGS)
  1677. + uinfo->value.enumerated.item = NUM_OF_SVM_SETTINGS - 1;
  1678. + strcpy(uinfo->value.enumerated.name,
  1679. + out_svm_set_enum_str[uinfo->value.enumerated.item]);
  1680. + return 0;
  1681. +}
  1682. +
  1683. +static int ca0132_alt_svm_setting_get(struct snd_kcontrol *kcontrol,
  1684. + struct snd_ctl_elem_value *ucontrol)
  1685. +{
  1686. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1687. + struct ca0132_spec *spec = codec->spec;
  1688. +
  1689. + ucontrol->value.enumerated.item[0] = spec->smart_volume_setting;
  1690. + return 0;
  1691. +}
  1692. +
  1693. +static int ca0132_alt_svm_setting_put(struct snd_kcontrol *kcontrol,
  1694. + struct snd_ctl_elem_value *ucontrol)
  1695. +{
  1696. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1697. + struct ca0132_spec *spec = codec->spec;
  1698. + int sel = ucontrol->value.enumerated.item[0];
  1699. + unsigned int items = NUM_OF_SVM_SETTINGS;
  1700. + unsigned int idx = SMART_VOLUME - EFFECT_START_NID;
  1701. + unsigned int tmp;
  1702. +
  1703. + if (sel >= items)
  1704. + return 0;
  1705. +
  1706. + codec_dbg(codec, "ca0132_alt_svm_setting: sel=%d, preset=%s\n",
  1707. + sel, out_svm_set_enum_str[sel]);
  1708. +
  1709. + spec->smart_volume_setting = sel;
  1710. +
  1711. + switch (sel) {
  1712. + case 0:
  1713. + tmp = FLOAT_ZERO;
  1714. + break;
  1715. + case 1:
  1716. + tmp = FLOAT_ONE;
  1717. + break;
  1718. + case 2:
  1719. + tmp = FLOAT_TWO;
  1720. + break;
  1721. + default:
  1722. + tmp = FLOAT_ZERO;
  1723. + break;
  1724. + }
  1725. + /* Req 2 is the Smart Volume Setting req. */
  1726. + dspio_set_uint_param(codec, ca0132_effects[idx].mid,
  1727. + ca0132_effects[idx].reqs[2], tmp);
  1728. + return 1;
  1729. +}
  1730. +
  1731. +/* Sound Blaster Z EQ preset controls */
  1732. +static int ca0132_alt_eq_preset_info(struct snd_kcontrol *kcontrol,
  1733. + struct snd_ctl_elem_info *uinfo)
  1734. +{
  1735. + unsigned int items = sizeof(ca0132_alt_eq_presets)
  1736. + / sizeof(struct ct_eq_preset);
  1737. +
  1738. + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
  1739. + uinfo->count = 1;
  1740. + uinfo->value.enumerated.items = items;
  1741. + if (uinfo->value.enumerated.item >= items)
  1742. + uinfo->value.enumerated.item = items - 1;
  1743. + strcpy(uinfo->value.enumerated.name,
  1744. + ca0132_alt_eq_presets[uinfo->value.enumerated.item].name);
  1745. + return 0;
  1746. +}
  1747. +
  1748. +static int ca0132_alt_eq_preset_get(struct snd_kcontrol *kcontrol,
  1749. + struct snd_ctl_elem_value *ucontrol)
  1750. +{
  1751. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1752. + struct ca0132_spec *spec = codec->spec;
  1753. +
  1754. + ucontrol->value.enumerated.item[0] = spec->eq_preset_val;
  1755. + return 0;
  1756. +}
  1757. +
  1758. +static int ca0132_alt_eq_preset_put(struct snd_kcontrol *kcontrol,
  1759. + struct snd_ctl_elem_value *ucontrol)
  1760. +{
  1761. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1762. + struct ca0132_spec *spec = codec->spec;
  1763. + int i, err = 0;
  1764. + int sel = ucontrol->value.enumerated.item[0];
  1765. + unsigned int items = sizeof(ca0132_alt_eq_presets)
  1766. + / sizeof(struct ct_eq_preset);
  1767. +
  1768. + if (sel >= items)
  1769. + return 0;
  1770. +
  1771. + codec_dbg(codec, "ca0132_alt_eq_preset_put: sel=%d, preset=%s\n",
  1772. + sel, ca0132_alt_eq_presets[sel].name);
  1773. +
  1774. + /*
  1775. + * Idx 0 is default.
  1776. + * Default needs to qualify with CrystalVoice state.
  1777. + */
  1778. + for (i = 0; i < EQ_PRESET_MAX_PARAM_COUNT; i++) {
  1779. + err = dspio_set_uint_param(codec, ca0132_alt_eq_enum.mid,
  1780. + ca0132_alt_eq_enum.reqs[i],
  1781. + ca0132_alt_eq_presets[sel].vals[i]);
  1782. + if (err < 0)
  1783. + break;
  1784. + }
  1785. +
  1786. + if (err >= 0) {
  1787. + spec->eq_preset_val = sel;
  1788. + }
  1789. +
  1790. + return 1;
  1791. +}
  1792. static int ca0132_voicefx_info(struct snd_kcontrol *kcontrol,
  1793. struct snd_ctl_elem_info *uinfo)
  1794. @@ -3753,10 +5243,15 @@
  1795. /* mic boost */
  1796. if (nid == spec->input_pins[0]) {
  1797. spec->cur_mic_boost = *valp;
  1798. + if (spec->use_alt_functions) {
  1799. + if (spec->in_enum_val != REAR_LINE_IN)
  1800. + changed = ca0132_mic_boost_set(codec, *valp);
  1801. + } else {
  1802. + /* Mic boost does not apply to Digital Mic */
  1803. + if (spec->cur_mic_type != DIGITAL_MIC)
  1804. + changed = ca0132_mic_boost_set(codec, *valp);
  1805. + }
  1806. - /* Mic boost does not apply to Digital Mic */
  1807. - if (spec->cur_mic_type != DIGITAL_MIC)
  1808. - changed = ca0132_mic_boost_set(codec, *valp);
  1809. goto exit;
  1810. }
  1811. @@ -3768,6 +5263,41 @@
  1812. /*
  1813. * Volume related
  1814. */
  1815. +/*
  1816. + * Sets the internal DSP decibel level to match the DAC for output, and the
  1817. + * ADC for input. Currently only the SBZ sets dsp capture volume level, and
  1818. + * all alternative codecs set DSP playback volume.
  1819. + */
  1820. +static void ca0132_alt_dsp_volume_put(struct hda_codec *codec, hda_nid_t nid)
  1821. +{
  1822. + struct ca0132_spec *spec = codec->spec;
  1823. + unsigned int dsp_dir;
  1824. + unsigned int lookup_val;
  1825. +
  1826. + if (nid == VNID_SPK)
  1827. + dsp_dir = DSP_VOL_OUT;
  1828. + else
  1829. + dsp_dir = DSP_VOL_IN;
  1830. +
  1831. + lookup_val = spec->vnode_lvol[nid - VNODE_START_NID];
  1832. +
  1833. + dspio_set_uint_param(codec,
  1834. + ca0132_alt_vol_ctls[dsp_dir].mid,
  1835. + ca0132_alt_vol_ctls[dsp_dir].reqs[0],
  1836. + float_vol_db_lookup[lookup_val]);
  1837. +
  1838. + lookup_val = spec->vnode_rvol[nid - VNODE_START_NID];
  1839. +
  1840. + dspio_set_uint_param(codec,
  1841. + ca0132_alt_vol_ctls[dsp_dir].mid,
  1842. + ca0132_alt_vol_ctls[dsp_dir].reqs[1],
  1843. + float_vol_db_lookup[lookup_val]);
  1844. +
  1845. + dspio_set_uint_param(codec,
  1846. + ca0132_alt_vol_ctls[dsp_dir].mid,
  1847. + ca0132_alt_vol_ctls[dsp_dir].reqs[2], FLOAT_ZERO);
  1848. +}
  1849. +
  1850. static int ca0132_volume_info(struct snd_kcontrol *kcontrol,
  1851. struct snd_ctl_elem_info *uinfo)
  1852. {
  1853. @@ -3869,6 +5399,51 @@
  1854. return changed;
  1855. }
  1856. +/*
  1857. + * This function is the same as the one above, because using an if statement
  1858. + * inside of the above volume control for the DSP volume would cause too much
  1859. + * lag. This is a lot more smooth.
  1860. + */
  1861. +static int ca0132_alt_volume_put(struct snd_kcontrol *kcontrol,
  1862. + struct snd_ctl_elem_value *ucontrol)
  1863. +{
  1864. + struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
  1865. + struct ca0132_spec *spec = codec->spec;
  1866. + hda_nid_t nid = get_amp_nid(kcontrol);
  1867. + int ch = get_amp_channels(kcontrol);
  1868. + long *valp = ucontrol->value.integer.value;
  1869. + hda_nid_t vnid = 0;
  1870. + int changed = 1;
  1871. +
  1872. + switch (nid) {
  1873. + case 0x02:
  1874. + vnid = VNID_SPK;
  1875. + break;
  1876. + case 0x07:
  1877. + vnid = VNID_MIC;
  1878. + break;
  1879. + }
  1880. +
  1881. + /* store the left and right volume */
  1882. + if (ch & 1) {
  1883. + spec->vnode_lvol[vnid - VNODE_START_NID] = *valp;
  1884. + valp++;
  1885. + }
  1886. + if (ch & 2) {
  1887. + spec->vnode_rvol[vnid - VNODE_START_NID] = *valp;
  1888. + valp++;
  1889. + }
  1890. +
  1891. + snd_hda_power_up(codec);
  1892. + ca0132_alt_dsp_volume_put(codec, vnid);
  1893. + mutex_lock(&codec->control_mutex);
  1894. + changed = snd_hda_mixer_amp_volume_put(kcontrol, ucontrol);
  1895. + mutex_unlock(&codec->control_mutex);
  1896. + snd_hda_power_down(codec);
  1897. +
  1898. + return changed;
  1899. +}
  1900. +
  1901. static int ca0132_volume_tlv(struct snd_kcontrol *kcontrol, int op_flag,
  1902. unsigned int size, unsigned int __user *tlv)
  1903. {
  1904. @@ -3907,14 +5482,61 @@
  1905. return err;
  1906. }
  1907. -static int add_fx_switch(struct hda_codec *codec, hda_nid_t nid,
  1908. +/* Add volume slider control for effect level */
  1909. +static int ca0132_alt_add_effect_slider(struct hda_codec *codec, hda_nid_t nid,
  1910. + const char *pfx, int dir)
  1911. +{
  1912. + char *fx = "FX:";
  1913. + char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
  1914. + int type = dir ? HDA_INPUT : HDA_OUTPUT;
  1915. + struct snd_kcontrol_new knew =
  1916. + HDA_CODEC_VOLUME_MONO(namestr, nid, 1, 0, type);
  1917. +
  1918. + sprintf(namestr, "%s %s %s Volume", fx, pfx, dirstr[dir]);
  1919. +
  1920. + knew.tlv.c = 0;
  1921. + knew.tlv.p = 0;
  1922. +
  1923. + switch (nid) {
  1924. + case XBASS_XOVER:
  1925. + knew.info = ca0132_alt_xbass_xover_slider_info;
  1926. + knew.get = ca0132_alt_xbass_xover_slider_ctl_get;
  1927. + knew.put = ca0132_alt_xbass_xover_slider_put;
  1928. + break;
  1929. + default:
  1930. + knew.info = ca0132_alt_effect_slider_info;
  1931. + knew.get = ca0132_alt_slider_ctl_get;
  1932. + knew.put = ca0132_alt_effect_slider_put;
  1933. + knew.private_value =
  1934. + HDA_COMPOSE_AMP_VAL(nid, 1, 0, type);
  1935. + break;
  1936. + }
  1937. +
  1938. + return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
  1939. +}
  1940. +
  1941. +/*
  1942. + * Added FX: prefix for the alternative codecs, because otherwise the surround
  1943. + * effect would conflict with the Surround sound volume control. Also seems more
  1944. + * clear as to what the switches do. Left alone for others.
  1945. + */
  1946. +static int add_fx_switch (struct hda_codec *codec, hda_nid_t nid,
  1947. const char *pfx, int dir)
  1948. {
  1949. + struct ca0132_spec *spec = codec->spec;
  1950. + char *fx = "FX:";
  1951. char namestr[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
  1952. int type = dir ? HDA_INPUT : HDA_OUTPUT;
  1953. struct snd_kcontrol_new knew =
  1954. CA0132_CODEC_MUTE_MONO(namestr, nid, 1, type);
  1955. - sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
  1956. + /* If using alt_controls, add FX: prefix. But, don't add FX:
  1957. + * prefix to OutFX or InFX enable controls.
  1958. + */
  1959. + if ((spec->use_alt_controls) && (nid <= IN_EFFECT_END_NID))
  1960. + sprintf(namestr, "%s %s %s Switch", fx, pfx, dirstr[dir]);
  1961. + else
  1962. + sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]);
  1963. +
  1964. return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec));
  1965. }
  1966. @@ -3929,6 +5551,111 @@
  1967. return snd_hda_ctl_add(codec, VOICEFX, snd_ctl_new1(&knew, codec));
  1968. }
  1969. +/* Create the EQ Preset control */
  1970. +static int add_ca0132_alt_eq_presets(struct hda_codec *codec)
  1971. +{
  1972. + struct snd_kcontrol_new knew =
  1973. + HDA_CODEC_MUTE_MONO(ca0132_alt_eq_enum.name,
  1974. + EQ_PRESET_ENUM, 1, 0, HDA_OUTPUT);
  1975. + knew.info = ca0132_alt_eq_preset_info;
  1976. + knew.get = ca0132_alt_eq_preset_get;
  1977. + knew.put = ca0132_alt_eq_preset_put;
  1978. + return snd_hda_ctl_add(codec, EQ_PRESET_ENUM,
  1979. + snd_ctl_new1(&knew, codec));
  1980. +}
  1981. +
  1982. +/* Add enumerated control for the three different settings of the smart volume
  1983. + * output effect. Normal just uses the slider value, and loud and night are
  1984. + * their own things that ignore that value. */
  1985. +static int ca0132_alt_add_svm_enum(struct hda_codec *codec)
  1986. +{
  1987. + struct snd_kcontrol_new knew =
  1988. + HDA_CODEC_MUTE_MONO("FX: Smart Volume Setting",
  1989. + SMART_VOLUME_ENUM, 1, 0, HDA_OUTPUT);
  1990. + knew.info = ca0132_alt_svm_setting_info;
  1991. + knew.get = ca0132_alt_svm_setting_get;
  1992. + knew.put = ca0132_alt_svm_setting_put;
  1993. + return snd_hda_ctl_add(codec, SMART_VOLUME_ENUM,
  1994. + snd_ctl_new1(&knew, codec));
  1995. +
  1996. +}
  1997. +
  1998. +/*
  1999. + * Create an Output Select enumerated control for codecs with surround
  2000. + * out capabilities.
  2001. + */
  2002. +static int ca0132_alt_add_output_enum(struct hda_codec *codec)
  2003. +{
  2004. + struct snd_kcontrol_new knew =
  2005. + HDA_CODEC_MUTE_MONO("Output Select",
  2006. + OUTPUT_SOURCE_ENUM, 1, 0, HDA_OUTPUT);
  2007. + knew.info = ca0132_alt_output_select_get_info;
  2008. + knew.get = ca0132_alt_output_select_get;
  2009. + knew.put = ca0132_alt_output_select_put;
  2010. + return snd_hda_ctl_add(codec, OUTPUT_SOURCE_ENUM,
  2011. + snd_ctl_new1(&knew, codec));
  2012. +}
  2013. +
  2014. +/*
  2015. + * Create an Input Source enumerated control for the alternate ca0132 codecs
  2016. + * because the front microphone has no auto-detect, and Line-in has to be set
  2017. + * somehow.
  2018. + */
  2019. +static int ca0132_alt_add_input_enum(struct hda_codec *codec)
  2020. +{
  2021. + struct snd_kcontrol_new knew =
  2022. + HDA_CODEC_MUTE_MONO("Input Source",
  2023. + INPUT_SOURCE_ENUM, 1, 0, HDA_INPUT);
  2024. + knew.info = ca0132_alt_input_source_info;
  2025. + knew.get = ca0132_alt_input_source_get;
  2026. + knew.put = ca0132_alt_input_source_put;
  2027. + return snd_hda_ctl_add(codec, INPUT_SOURCE_ENUM,
  2028. + snd_ctl_new1(&knew, codec));
  2029. +}
  2030. +
  2031. +/*
  2032. + * Add mic boost enumerated control. Switches through 0dB to 30dB. This adds
  2033. + * more control than the original mic boost, which is either full 30dB or off.
  2034. + */
  2035. +static int ca0132_alt_add_mic_boost_enum(struct hda_codec *codec)
  2036. +{
  2037. + struct snd_kcontrol_new knew =
  2038. + HDA_CODEC_MUTE_MONO("Mic Boost Capture Switch",
  2039. + MIC_BOOST_ENUM, 1, 0, HDA_INPUT);
  2040. + knew.info = ca0132_alt_mic_boost_info;
  2041. + knew.get = ca0132_alt_mic_boost_get;
  2042. + knew.put = ca0132_alt_mic_boost_put;
  2043. + return snd_hda_ctl_add(codec, MIC_BOOST_ENUM,
  2044. + snd_ctl_new1(&knew, codec));
  2045. +
  2046. +}
  2047. +
  2048. +/*
  2049. + * Need to create slave controls for the alternate codecs that have surround
  2050. + * capabilities.
  2051. + */
  2052. +static const char * const ca0132_alt_slave_pfxs[] = {
  2053. + "Front", "Surround", "Center", "LFE", NULL,
  2054. +};
  2055. +
  2056. +/*
  2057. + * Also need special channel map, because the default one is incorrect.
  2058. + * I think this has to do with the pin for rear surround being 0x11,
  2059. + * and the center/lfe being 0x10. Usually the pin order is the opposite.
  2060. + */
  2061. +const struct snd_pcm_chmap_elem ca0132_alt_chmaps[] = {
  2062. + { .channels = 2,
  2063. + .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
  2064. + { .channels = 4,
  2065. + .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
  2066. + SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
  2067. + { .channels = 6,
  2068. + .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
  2069. + SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE,
  2070. + SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
  2071. + { }
  2072. +};
  2073. +
  2074. /*
  2075. * When changing Node IDs for Mixer Controls below, make sure to update
  2076. * Node IDs in ca0132_config() as well.
  2077. @@ -3955,66 +5682,199 @@
  2078. { } /* end */
  2079. };
  2080. +/*
  2081. + * SBZ specific control mixer. Removes auto-detect for mic, and adds surround
  2082. + * controls. Also sets both the Front Playback and Capture Volume controls to
  2083. + * alt so they set the DSP's decibel level.
  2084. + */
  2085. +static struct snd_kcontrol_new sbz_mixer[] = {
  2086. + CA0132_ALT_CODEC_VOL("Front Playback Volume", 0x02, HDA_OUTPUT),
  2087. + CA0132_CODEC_MUTE("Front Playback Switch", VNID_SPK, HDA_OUTPUT),
  2088. + HDA_CODEC_VOLUME("Surround Playback Volume", 0x04, 0, HDA_OUTPUT),
  2089. + HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0, HDA_OUTPUT),
  2090. + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x03, 1, 0, HDA_OUTPUT),
  2091. + HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x03, 1, 0, HDA_OUTPUT),
  2092. + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x03, 2, 0, HDA_OUTPUT),
  2093. + HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x03, 2, 0, HDA_OUTPUT),
  2094. + CA0132_ALT_CODEC_VOL("Capture Volume", 0x07, HDA_INPUT),
  2095. + CA0132_CODEC_MUTE("Capture Switch", VNID_MIC, HDA_INPUT),
  2096. + HDA_CODEC_VOLUME("What U Hear Capture Volume", 0x0a, 0, HDA_INPUT),
  2097. + HDA_CODEC_MUTE("What U Hear Capture Switch", 0x0a, 0, HDA_INPUT),
  2098. + CA0132_CODEC_MUTE_MONO("HP/Speaker Auto Detect Playback Switch",
  2099. + VNID_HP_ASEL, 1, HDA_OUTPUT),
  2100. + { } /* end */
  2101. +};
  2102. +
  2103. +/*
  2104. + * Same as the Sound Blaster Z, except doesn't use the alt volume for capture
  2105. + * because it doesn't set decibel levels for the DSP for capture.
  2106. + */
  2107. +static struct snd_kcontrol_new r3di_mixer[] = {
  2108. + CA0132_ALT_CODEC_VOL("Front Playback Volume", 0x02, HDA_OUTPUT),
  2109. + CA0132_CODEC_MUTE("Front Playback Switch", VNID_SPK, HDA_OUTPUT),
  2110. + HDA_CODEC_VOLUME("Surround Playback Volume", 0x04, 0, HDA_OUTPUT),
  2111. + HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0, HDA_OUTPUT),
  2112. + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x03, 1, 0, HDA_OUTPUT),
  2113. + HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x03, 1, 0, HDA_OUTPUT),
  2114. + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x03, 2, 0, HDA_OUTPUT),
  2115. + HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x03, 2, 0, HDA_OUTPUT),
  2116. + CA0132_CODEC_VOL("Capture Volume", VNID_MIC, HDA_INPUT),
  2117. + CA0132_CODEC_MUTE("Capture Switch", VNID_MIC, HDA_INPUT),
  2118. + HDA_CODEC_VOLUME("What U Hear Capture Volume", 0x0a, 0, HDA_INPUT),
  2119. + HDA_CODEC_MUTE("What U Hear Capture Switch", 0x0a, 0, HDA_INPUT),
  2120. + CA0132_CODEC_MUTE_MONO("HP/Speaker Auto Detect Playback Switch",
  2121. + VNID_HP_ASEL, 1, HDA_OUTPUT),
  2122. + { } /* end */
  2123. +};
  2124. +
  2125. static int ca0132_build_controls(struct hda_codec *codec)
  2126. {
  2127. - struct ca0132_spec *spec = codec->spec;
  2128. - int i, num_fx;
  2129. - int err = 0;
  2130. + struct ca0132_spec *spec = codec->spec;
  2131. + struct hda_pcm *pcm;
  2132. + int i, num_fx, num_sliders;
  2133. + int err = 0;
  2134. +
  2135. + /* Add Mixer controls */
  2136. + for (i = 0; i < spec->num_mixers; i++) {
  2137. + err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
  2138. + if (err < 0)
  2139. + return err;
  2140. + }
  2141. + /* Setup vmaster with surround slaves for desktop ca0132 devices */
  2142. + if (spec->use_alt_functions) {
  2143. + snd_hda_set_vmaster_tlv(codec, spec->dacs[0], HDA_OUTPUT,
  2144. + spec->tlv);
  2145. + snd_hda_add_vmaster(codec, "Master Playback Volume",
  2146. + spec->tlv, ca0132_alt_slave_pfxs,
  2147. + "Playback Volume");
  2148. + err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
  2149. + NULL, ca0132_alt_slave_pfxs,
  2150. + "Playback Switch",
  2151. + true, &spec->vmaster_mute.sw_kctl);
  2152. +
  2153. + }
  2154. +
  2155. + /* Add in and out effects controls.
  2156. + * VoiceFX, PE and CrystalVoice are added separately.
  2157. + */
  2158. + num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
  2159. + for (i = 0; i < num_fx; i++) {
  2160. + /* SBZ breaks if Echo Cancellation is used */
  2161. + if (spec->quirk == QUIRK_SBZ) {
  2162. + if (i == (ECHO_CANCELLATION - IN_EFFECT_START_NID +
  2163. + OUT_EFFECTS_COUNT))
  2164. + continue;
  2165. + }
  2166. - /* Add Mixer controls */
  2167. - for (i = 0; i < spec->num_mixers; i++) {
  2168. - err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
  2169. + err = add_fx_switch (codec, ca0132_effects[i].nid,
  2170. + ca0132_effects[i].name,
  2171. + ca0132_effects[i].direct);
  2172. + if (err < 0)
  2173. + return err;
  2174. + }
  2175. + /*
  2176. + * If codec has use_alt_controls set to true, add effect level sliders,
  2177. + * EQ presets, and Smart Volume presets. Also, change names to add FX
  2178. + * prefix, and change PlayEnhancement and CrystalVoice to match.
  2179. + */
  2180. + if (spec->use_alt_controls) {
  2181. + ca0132_alt_add_svm_enum(codec);
  2182. + add_ca0132_alt_eq_presets(codec);
  2183. + err = add_fx_switch (codec, PLAY_ENHANCEMENT,
  2184. + "Enable OutFX", 0);
  2185. if (err < 0)
  2186. return err;
  2187. - }
  2188. - /* Add in and out effects controls.
  2189. - * VoiceFX, PE and CrystalVoice are added separately.
  2190. - */
  2191. - num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
  2192. - for (i = 0; i < num_fx; i++) {
  2193. - err = add_fx_switch(codec, ca0132_effects[i].nid,
  2194. - ca0132_effects[i].name,
  2195. - ca0132_effects[i].direct);
  2196. + err = add_fx_switch (codec, CRYSTAL_VOICE,
  2197. + "Enable InFX", 1);
  2198. if (err < 0)
  2199. return err;
  2200. - }
  2201. - err = add_fx_switch(codec, PLAY_ENHANCEMENT, "PlayEnhancement", 0);
  2202. - if (err < 0)
  2203. - return err;
  2204. + num_sliders = OUT_EFFECTS_COUNT - 1;
  2205. + for (i = 0; i < num_sliders; i++) {
  2206. + err = ca0132_alt_add_effect_slider(codec,
  2207. + ca0132_effects[i].nid,
  2208. + ca0132_effects[i].name,
  2209. + ca0132_effects[i].direct);
  2210. + if (err < 0)
  2211. + return err;
  2212. + }
  2213. - err = add_fx_switch(codec, CRYSTAL_VOICE, "CrystalVoice", 1);
  2214. - if (err < 0)
  2215. - return err;
  2216. + err = ca0132_alt_add_effect_slider(codec, XBASS_XOVER,
  2217. + "X-Bass Crossover", EFX_DIR_OUT);
  2218. - add_voicefx(codec);
  2219. + if (err < 0)
  2220. + return err;
  2221. + } else {
  2222. + err = add_fx_switch (codec, PLAY_ENHANCEMENT,
  2223. + "PlayEnhancement", 0);
  2224. + if (err < 0)
  2225. + return err;
  2226. +
  2227. + err = add_fx_switch (codec, CRYSTAL_VOICE,
  2228. + "CrystalVoice", 1);
  2229. + if (err < 0)
  2230. + return err;
  2231. + }
  2232. + add_voicefx(codec);
  2233. + /*
  2234. + * If the codec uses alt_functions, you need the enumerated controls
  2235. + * to select the new outputs and inputs, plus add the new mic boost
  2236. + * setting control.
  2237. + */
  2238. + if (spec->use_alt_functions) {
  2239. + ca0132_alt_add_output_enum(codec);
  2240. + ca0132_alt_add_input_enum(codec);
  2241. + ca0132_alt_add_mic_boost_enum(codec);
  2242. +
  2243. + }
  2244. #ifdef ENABLE_TUNING_CONTROLS
  2245. - add_tuning_ctls(codec);
  2246. + add_tuning_ctls(codec);
  2247. #endif
  2248. - err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
  2249. - if (err < 0)
  2250. - return err;
  2251. - if (spec->dig_out) {
  2252. - err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
  2253. - spec->dig_out);
  2254. - if (err < 0)
  2255. - return err;
  2256. - err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
  2257. - if (err < 0)
  2258. - return err;
  2259. - /* spec->multiout.share_spdif = 1; */
  2260. - }
  2261. + err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
  2262. + if (err < 0)
  2263. + return err;
  2264. +
  2265. + if (spec->dig_out) {
  2266. + err = snd_hda_create_spdif_out_ctls(codec, spec->dig_out,
  2267. + spec->dig_out);
  2268. + if (err < 0)
  2269. + return err;
  2270. + err = snd_hda_create_spdif_share_sw(codec, &spec->multiout);
  2271. + if (err < 0)
  2272. + return err;
  2273. + /* spec->multiout.share_spdif = 1; */
  2274. + }
  2275. +
  2276. + if (spec->dig_in) {
  2277. + err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
  2278. + if (err < 0)
  2279. + return err;
  2280. + }
  2281. +
  2282. + /* if there is a possibility of having 6 channels, set up the proper
  2283. + * chmap. The ca0132 has a funky setup that needs FR,FL,FC,LFE,RR,RL
  2284. + * instead of the more common FR,FL,RR,RL,FC,LFE. Not sure why.
  2285. + */
  2286. + list_for_each_entry(pcm, &codec->pcm_list_head, list) {
  2287. + struct hda_pcm_stream *hinfo = &pcm->stream[SNDRV_PCM_STREAM_PLAYBACK];
  2288. + struct snd_pcm_chmap *chmap;
  2289. + const struct snd_pcm_chmap_elem *elem;
  2290. + elem = ca0132_alt_chmaps;
  2291. + codec_dbg(codec, "Name: %s Channels Max: %d ", pcm->name, hinfo->channels_max);
  2292. + if (hinfo->channels_max == 6) {
  2293. + err = snd_pcm_add_chmap_ctls(pcm->pcm,
  2294. + SNDRV_PCM_STREAM_PLAYBACK,
  2295. + elem, hinfo->channels_max, 0, &chmap);
  2296. + if (err < 0)
  2297. + codec_dbg(codec, "snd_pcm_add_chmap_ctls failed!");
  2298. + }
  2299. + }
  2300. - if (spec->dig_in) {
  2301. - err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in);
  2302. - if (err < 0)
  2303. - return err;
  2304. - }
  2305. - return 0;
  2306. + return 0;
  2307. }
  2308. /*
  2309. @@ -4068,6 +5928,11 @@
  2310. info = snd_hda_codec_pcm_new(codec, "CA0132 Analog");
  2311. if (!info)
  2312. return -ENOMEM;
  2313. + if (spec->use_alt_functions) {
  2314. + info->own_chmap = true;
  2315. + info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap
  2316. + = ca0132_alt_chmaps;
  2317. + }
  2318. info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ca0132_pcm_analog_playback;
  2319. info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->dacs[0];
  2320. info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
  2321. @@ -4076,12 +5941,15 @@
  2322. info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
  2323. info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[0];
  2324. - info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2");
  2325. - if (!info)
  2326. - return -ENOMEM;
  2327. - info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
  2328. - info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
  2329. - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1];
  2330. + /* With the DSP enabled, desktops don't use this ADC. */
  2331. + if (spec->use_alt_functions) {
  2332. + info = snd_hda_codec_pcm_new(codec, "CA0132 Analog Mic-In2");
  2333. + if (!info)
  2334. + return -ENOMEM;
  2335. + info->stream[SNDRV_PCM_STREAM_CAPTURE] = ca0132_pcm_analog_capture;
  2336. + info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = 1;
  2337. + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adcs[1];
  2338. + }
  2339. info = snd_hda_codec_pcm_new(codec, "CA0132 What U Hear");
  2340. if (!info)
  2341. @@ -4288,6 +6156,194 @@
  2342. }
  2343. /*
  2344. + * Recon3Di r3di_setup_defaults sub functions.
  2345. + */
  2346. +
  2347. +static void r3di_dsp_scp_startup(struct hda_codec *codec)
  2348. +{
  2349. + unsigned int tmp;
  2350. +
  2351. + tmp = 0x00000000;
  2352. + dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
  2353. +
  2354. + tmp = 0x00000001;
  2355. + dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
  2356. +
  2357. + tmp = 0x00000004;
  2358. + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
  2359. +
  2360. + tmp = 0x00000005;
  2361. + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
  2362. +
  2363. + tmp = 0x00000000;
  2364. + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
  2365. +
  2366. +}
  2367. +
  2368. +static void r3di_dsp_initial_mic_setup(struct hda_codec *codec)
  2369. +{
  2370. + unsigned int tmp;
  2371. +
  2372. + /* Mic 1 Setup */
  2373. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
  2374. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
  2375. + /* This ConnPointID is unique to Recon3Di. Haven't seen it elsewhere */
  2376. + chipio_set_conn_rate(codec, 0x0F, SR_96_000);
  2377. + tmp = FLOAT_ONE;
  2378. + dspio_set_uint_param(codec, 0x80, 0x00, tmp);
  2379. +
  2380. + /* Mic 2 Setup, even though it isn't connected on SBZ */
  2381. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN2, SR_96_000);
  2382. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2, SR_96_000);
  2383. + chipio_set_conn_rate(codec, 0x0F, SR_96_000);
  2384. + tmp = FLOAT_ZERO;
  2385. + dspio_set_uint_param(codec, 0x80, 0x01, tmp);
  2386. +}
  2387. +
  2388. +/*
  2389. + * Initialize Sound Blaster Z analog microphones.
  2390. + */
  2391. +static void sbz_init_analog_mics(struct hda_codec *codec)
  2392. +{
  2393. + unsigned int tmp;
  2394. +
  2395. + /* Mic 1 Setup */
  2396. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
  2397. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
  2398. + tmp = FLOAT_THREE;
  2399. + dspio_set_uint_param(codec, 0x80, 0x00, tmp);
  2400. +
  2401. + /* Mic 2 Setup, even though it isn't connected on SBZ */
  2402. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN2, SR_96_000);
  2403. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT2, SR_96_000);
  2404. + tmp = FLOAT_ZERO;
  2405. + dspio_set_uint_param(codec, 0x80, 0x01, tmp);
  2406. +
  2407. +}
  2408. +
  2409. +/*
  2410. + * Sets the source of stream 0x14 to connpointID 0x48, and the destination
  2411. + * connpointID to 0x91. If this isn't done, the destination is 0x71, and
  2412. + * you get no sound. I'm guessing this has to do with the Sound Blaster Z
  2413. + * having an updated DAC, which changes the destination to that DAC.
  2414. + */
  2415. +static void sbz_connect_streams(struct hda_codec *codec)
  2416. +{
  2417. + struct ca0132_spec *spec = codec->spec;
  2418. +
  2419. + mutex_lock(&spec->chipio_mutex);
  2420. +
  2421. + codec_dbg(codec, "Connect Streams entered, mutex locked and loaded.\n");
  2422. +
  2423. + chipio_set_stream_channels(codec, 0x0C, 6);
  2424. + chipio_set_stream_control(codec, 0x0C, 1);
  2425. +
  2426. + /* This value is 0x43 for 96khz, and 0x83 for 192khz. */
  2427. + chipio_write_no_mutex(codec, 0x18a020, 0x00000043);
  2428. +
  2429. + /* Setup stream 0x14 with it's source and destination points */
  2430. + chipio_set_stream_source_dest(codec, 0x14, 0x48, 0x91);
  2431. + chipio_set_conn_rate_no_mutex(codec, 0x48, SR_96_000);
  2432. + chipio_set_conn_rate_no_mutex(codec, 0x91, SR_96_000);
  2433. + chipio_set_stream_channels(codec, 0x14, 2);
  2434. + chipio_set_stream_control(codec, 0x14, 1);
  2435. +
  2436. + codec_dbg(codec, "Connect Streams exited, mutex released.\n");
  2437. +
  2438. + mutex_unlock(&spec->chipio_mutex);
  2439. +
  2440. +}
  2441. +
  2442. +/*
  2443. + * Write data through ChipIO to setup proper stream destinations.
  2444. + * Not sure how it exactly works, but it seems to direct data
  2445. + * to different destinations. Example is f8 to c0, e0 to c0.
  2446. + * All I know is, if you don't set these, you get no sound.
  2447. + */
  2448. +static void sbz_chipio_startup_data(struct hda_codec *codec)
  2449. +{
  2450. + struct ca0132_spec *spec = codec->spec;
  2451. + mutex_lock(&spec->chipio_mutex);
  2452. +
  2453. + codec_dbg(codec, "Startup Data entered, mutex locked and loaded.\n");
  2454. +
  2455. + /* These control audio output */
  2456. + chipio_write_no_mutex(codec, 0x190060, 0x0001f8c0);
  2457. + chipio_write_no_mutex(codec, 0x190064, 0x0001f9c1);
  2458. + chipio_write_no_mutex(codec, 0x190068, 0x0001fac6);
  2459. + chipio_write_no_mutex(codec, 0x19006c, 0x0001fbc7);
  2460. + /* Signal to update I think */
  2461. + chipio_write_no_mutex(codec, 0x19042c, 0x00000001);
  2462. +
  2463. + chipio_set_stream_channels(codec, 0x0C, 6);
  2464. + chipio_set_stream_control(codec, 0x0C, 1);
  2465. + /* No clue what these control */
  2466. + chipio_write_no_mutex(codec, 0x190030, 0x0001e0c0);
  2467. + chipio_write_no_mutex(codec, 0x190034, 0x0001e1c1);
  2468. + chipio_write_no_mutex(codec, 0x190038, 0x0001e4c2);
  2469. + chipio_write_no_mutex(codec, 0x19003c, 0x0001e5c3);
  2470. + chipio_write_no_mutex(codec, 0x190040, 0x0001e2c4);
  2471. + chipio_write_no_mutex(codec, 0x190044, 0x0001e3c5);
  2472. + chipio_write_no_mutex(codec, 0x190048, 0x0001e8c6);
  2473. + chipio_write_no_mutex(codec, 0x19004c, 0x0001e9c7);
  2474. + chipio_write_no_mutex(codec, 0x190050, 0x0001ecc8);
  2475. + chipio_write_no_mutex(codec, 0x190054, 0x0001edc9);
  2476. + chipio_write_no_mutex(codec, 0x190058, 0x0001eaca);
  2477. + chipio_write_no_mutex(codec, 0x19005c, 0x0001ebcb);
  2478. +
  2479. + chipio_write_no_mutex(codec, 0x19042c, 0x00000001);
  2480. +
  2481. + codec_dbg(codec, "Startup Data exited, mutex released.\n");
  2482. +
  2483. + mutex_unlock(&spec->chipio_mutex);
  2484. +}
  2485. +/* Sound Blaster Z uses these after DSP is loaded. Weird SCP commands
  2486. + * without a 0x20 source like normal. */
  2487. +static void sbz_dsp_scp_startup(struct hda_codec *codec)
  2488. +{
  2489. + unsigned int tmp;
  2490. +
  2491. + tmp = 0x00000003;
  2492. + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
  2493. +
  2494. + tmp = 0x00000000;
  2495. + dspio_set_uint_param_no_source(codec, 0x80, 0x0A, tmp);
  2496. +
  2497. + tmp = 0x00000001;
  2498. + dspio_set_uint_param_no_source(codec, 0x80, 0x0B, tmp);
  2499. +
  2500. + tmp = 0x00000004;
  2501. + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
  2502. +
  2503. + tmp = 0x00000005;
  2504. + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
  2505. +
  2506. + tmp = 0x00000000;
  2507. + dspio_set_uint_param_no_source(codec, 0x80, 0x0C, tmp);
  2508. +
  2509. +}
  2510. +
  2511. +static void sbz_dsp_initial_mic_setup(struct hda_codec *codec)
  2512. +{
  2513. + unsigned int tmp;
  2514. +
  2515. + chipio_set_stream_control(codec, 0x03, 0);
  2516. + chipio_set_stream_control(codec, 0x04, 0);
  2517. +
  2518. + chipio_set_conn_rate(codec, MEM_CONNID_MICIN1, SR_96_000);
  2519. + chipio_set_conn_rate(codec, MEM_CONNID_MICOUT1, SR_96_000);
  2520. +
  2521. + tmp = FLOAT_THREE;
  2522. + dspio_set_uint_param(codec, 0x80, 0x00, tmp);
  2523. +
  2524. + chipio_set_stream_control(codec, 0x03, 1);
  2525. + chipio_set_stream_control(codec, 0x04, 1);
  2526. +
  2527. + chipio_write(codec, 0x18b098, 0x0000000c);
  2528. + chipio_write(codec, 0x18b09C, 0x0000000c);
  2529. +}
  2530. +
  2531. +/*
  2532. * Setup default parameters for DSP
  2533. */
  2534. static void ca0132_setup_defaults(struct hda_codec *codec)
  2535. @@ -4332,16 +6388,150 @@
  2536. }
  2537. /*
  2538. + * Setup default parameters for Recon3Di DSP.
  2539. + */
  2540. +
  2541. +static void r3di_setup_defaults(struct hda_codec *codec)
  2542. +{
  2543. + struct ca0132_spec *spec = codec->spec;
  2544. + unsigned int tmp;
  2545. + int num_fx;
  2546. + int idx, i;
  2547. +
  2548. + if (spec->dsp_state != DSP_DOWNLOADED)
  2549. + return;
  2550. +
  2551. + r3di_dsp_scp_startup(codec);
  2552. +
  2553. + r3di_dsp_initial_mic_setup(codec);
  2554. +
  2555. + /*remove DSP headroom*/
  2556. + tmp = FLOAT_ZERO;
  2557. + dspio_set_uint_param(codec, 0x96, 0x3C, tmp);
  2558. +
  2559. + /* set WUH source */
  2560. + tmp = FLOAT_TWO;
  2561. + dspio_set_uint_param(codec, 0x31, 0x00, tmp);
  2562. + chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
  2563. +
  2564. + /* Set speaker source? */
  2565. + dspio_set_uint_param(codec, 0x32, 0x00, tmp);
  2566. +
  2567. + r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED);
  2568. +
  2569. + /* Setup effect defaults */
  2570. + num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
  2571. + for (idx = 0; idx < num_fx; idx++) {
  2572. + for (i = 0; i <= ca0132_effects[idx].params; i++) {
  2573. + dspio_set_uint_param(codec, ca0132_effects[idx].mid,
  2574. + ca0132_effects[idx].reqs[i],
  2575. + ca0132_effects[idx].def_vals[i]);
  2576. + }
  2577. + }
  2578. +
  2579. +}
  2580. +
  2581. +/*
  2582. + * Setup default parameters for the Sound Blaster Z DSP. A lot more going on
  2583. + * than the Chromebook setup.
  2584. + */
  2585. +static void sbz_setup_defaults(struct hda_codec *codec)
  2586. +{
  2587. + struct ca0132_spec *spec = codec->spec;
  2588. + unsigned int tmp, stream_format;
  2589. + int num_fx;
  2590. + int idx, i;
  2591. +
  2592. + if (spec->quirk == QUIRK_SBZ)
  2593. + sbz_dsp_scp_startup(codec);
  2594. +
  2595. + if (spec->dsp_state != DSP_DOWNLOADED)
  2596. + return;
  2597. +
  2598. + sbz_dsp_scp_startup(codec);
  2599. +
  2600. + sbz_init_analog_mics(codec);
  2601. +
  2602. + sbz_connect_streams(codec);
  2603. +
  2604. + sbz_chipio_startup_data(codec);
  2605. +
  2606. + chipio_set_stream_control(codec, 0x03, 1);
  2607. + chipio_set_stream_control(codec, 0x04, 1);
  2608. +
  2609. + /* Sets internal input loopback to off, used to have a switch to
  2610. + * enable input loopback, but turned out to be way too buggy. */
  2611. + tmp = FLOAT_ONE;
  2612. + dspio_set_uint_param(codec, 0x37, 0x08, tmp);
  2613. + dspio_set_uint_param(codec, 0x37, 0x10, tmp);
  2614. +
  2615. + /*remove DSP headroom*/
  2616. + tmp = FLOAT_ZERO;
  2617. + dspio_set_uint_param(codec, 0x96, 0x3C, tmp);
  2618. +
  2619. + /* set WUH source */
  2620. + tmp = FLOAT_TWO;
  2621. + dspio_set_uint_param(codec, 0x31, 0x00, tmp);
  2622. + chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
  2623. +
  2624. + /* Set speaker source? */
  2625. + dspio_set_uint_param(codec, 0x32, 0x00, tmp);
  2626. +
  2627. + sbz_dsp_initial_mic_setup(codec);
  2628. +
  2629. +
  2630. + /* out, in effects + voicefx */
  2631. + num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
  2632. + for (idx = 0; idx < num_fx; idx++) {
  2633. + for (i = 0; i <= ca0132_effects[idx].params; i++) {
  2634. + dspio_set_uint_param(codec, ca0132_effects[idx].mid,
  2635. + ca0132_effects[idx].reqs[i],
  2636. + ca0132_effects[idx].def_vals[i]);
  2637. + }
  2638. + }
  2639. +
  2640. + /* Have to make a stream to bind the sound output to, otherwise
  2641. + * you'll get dead audio. Before I did this, it would bind to an
  2642. + * audio input, and would never work */
  2643. + stream_format = snd_hdac_calc_stream_format(48000, 2, SNDRV_PCM_FORMAT_S32_LE, 32, 0);
  2644. +
  2645. + snd_hda_codec_setup_stream(codec, spec->dacs[0], spec->dsp_stream_id,
  2646. + 0, stream_format);
  2647. +
  2648. + snd_hda_codec_cleanup_stream(codec, spec->dacs[0]);
  2649. +
  2650. + snd_hda_codec_setup_stream(codec, spec->dacs[0], spec->dsp_stream_id,
  2651. + 0, stream_format);
  2652. +
  2653. + snd_hda_codec_cleanup_stream(codec, spec->dacs[0]);
  2654. +
  2655. + return;
  2656. +}
  2657. +
  2658. +/*
  2659. * Initialization of flags in chip
  2660. */
  2661. static void ca0132_init_flags(struct hda_codec *codec)
  2662. {
  2663. - chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0);
  2664. - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_COMMON_MODE, 0);
  2665. - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_COMMON_MODE, 0);
  2666. - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_10KOHM_LOAD, 0);
  2667. - chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0);
  2668. - chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_HIGH_PASS, 1);
  2669. + struct ca0132_spec *spec = codec->spec;
  2670. + if (spec->use_alt_functions) {
  2671. + chipio_set_control_flag(codec, CONTROL_FLAG_DSP_96KHZ, 1);
  2672. + chipio_set_control_flag(codec, CONTROL_FLAG_DAC_96KHZ, 1);
  2673. + chipio_set_control_flag(codec, CONTROL_FLAG_ADC_B_96KHZ, 1);
  2674. + chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_96KHZ, 1);
  2675. + chipio_set_control_flag(codec, CONTROL_FLAG_SRC_RATE_96KHZ, 1);
  2676. + chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0);
  2677. + chipio_set_control_flag(codec, CONTROL_FLAG_SPDIF2OUT, 0);
  2678. + chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0);
  2679. + chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_10KOHM_LOAD, 1);
  2680. + } else {
  2681. + chipio_set_control_flag(codec, CONTROL_FLAG_IDLE_ENABLE, 0);
  2682. + chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_COMMON_MODE, 0);
  2683. + chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_COMMON_MODE, 0);
  2684. + chipio_set_control_flag(codec, CONTROL_FLAG_PORT_A_10KOHM_LOAD, 0);
  2685. + chipio_set_control_flag(codec, CONTROL_FLAG_PORT_D_10KOHM_LOAD, 0);
  2686. + chipio_set_control_flag(codec, CONTROL_FLAG_ADC_C_HIGH_PASS, 1);
  2687. + }
  2688. }
  2689. /*
  2690. @@ -4349,8 +6539,17 @@
  2691. */
  2692. static void ca0132_init_params(struct hda_codec *codec)
  2693. {
  2694. - chipio_set_control_param(codec, CONTROL_PARAM_PORTA_160OHM_GAIN, 6);
  2695. - chipio_set_control_param(codec, CONTROL_PARAM_PORTD_160OHM_GAIN, 6);
  2696. + struct ca0132_spec *spec = codec->spec;
  2697. + if (spec->use_alt_functions) {
  2698. + chipio_set_conn_rate(codec, MEM_CONNID_WUH, SR_48_000);
  2699. + chipio_set_conn_rate(codec, 0x0B, SR_48_000);
  2700. + chipio_set_control_param(codec, CONTROL_PARAM_SPDIF1_SOURCE, 0);
  2701. + chipio_set_control_param(codec, 0, 0); // Dunno what this param is.
  2702. + chipio_set_control_param(codec, CONTROL_PARAM_VIP_SOURCE, 0);
  2703. + }
  2704. +
  2705. + chipio_set_control_param(codec, CONTROL_PARAM_PORTA_160OHM_GAIN, 6);
  2706. + chipio_set_control_param(codec, CONTROL_PARAM_PORTD_160OHM_GAIN, 6);
  2707. }
  2708. static void ca0132_set_dsp_msr(struct hda_codec *codec, bool is96k)
  2709. @@ -4369,25 +6568,63 @@
  2710. static bool ca0132_download_dsp_images(struct hda_codec *codec)
  2711. {
  2712. - bool dsp_loaded = false;
  2713. - const struct dsp_image_seg *dsp_os_image;
  2714. - const struct firmware *fw_entry;
  2715. + bool dsp_loaded = false;
  2716. + struct ca0132_spec *spec = codec->spec;
  2717. + const struct dsp_image_seg *dsp_os_image;
  2718. + const struct firmware *fw_entry;
  2719. + /*
  2720. + * Alternate firmwares for different variants. The Recon3Di apparently
  2721. + * can use the default firmware, but I'll leave the option in case
  2722. + * it needs it again.
  2723. + */
  2724. + switch (spec->quirk) {
  2725. + case QUIRK_SBZ:
  2726. + if (request_firmware(&fw_entry, SBZ_EFX_FILE,
  2727. + codec->card->dev) != 0) {
  2728. + codec_dbg(codec, "SBZ alt firmware not detected. ");
  2729. + spec->alt_firmware_present = false;
  2730. + } else {
  2731. + codec_dbg(codec, "Sound Blaster Z firmware selected.");
  2732. + spec->alt_firmware_present = true;
  2733. + }
  2734. + break;
  2735. + case QUIRK_R3DI:
  2736. + if (request_firmware(&fw_entry, R3DI_EFX_FILE,
  2737. + codec->card->dev) != 0) {
  2738. + codec_dbg(codec, "Recon3Di alt firmware not detected.");
  2739. + spec->alt_firmware_present = false;
  2740. + } else {
  2741. + codec_dbg(codec, "Recon3Di firmware selected.");
  2742. + spec->alt_firmware_present = true;
  2743. + }
  2744. + break;
  2745. + default:
  2746. + spec->alt_firmware_present = false;
  2747. + break;
  2748. + }
  2749. + /* Use default ctefx.bin if no alt firmware is detected, or if none
  2750. + * exists for your particular codec. */
  2751. + if (spec->alt_firmware_present == false) {
  2752. + codec_dbg(codec, "Default firmware selected.");
  2753. + if (request_firmware(&fw_entry, EFX_FILE,
  2754. + codec->card->dev) != 0)
  2755. + return false;
  2756. + }
  2757. +
  2758. + codec_dbg(codec, "Inside ca0132_download_dsp_images");
  2759. +
  2760. + dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
  2761. + if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) {
  2762. + codec_err(codec, "ca0132 DSP load image failed\n");
  2763. + goto exit_download;
  2764. + }
  2765. - if (request_firmware(&fw_entry, EFX_FILE, codec->card->dev) != 0)
  2766. - return false;
  2767. -
  2768. - dsp_os_image = (struct dsp_image_seg *)(fw_entry->data);
  2769. - if (dspload_image(codec, dsp_os_image, 0, 0, true, 0)) {
  2770. - codec_err(codec, "ca0132 DSP load image failed\n");
  2771. - goto exit_download;
  2772. - }
  2773. -
  2774. - dsp_loaded = dspload_wait_loaded(codec);
  2775. + dsp_loaded = dspload_wait_loaded(codec);
  2776. exit_download:
  2777. - release_firmware(fw_entry);
  2778. + release_firmware(fw_entry);
  2779. - return dsp_loaded;
  2780. + return dsp_loaded;
  2781. }
  2782. static void ca0132_download_dsp(struct hda_codec *codec)
  2783. @@ -4402,13 +6639,17 @@
  2784. return; /* don't retry failures */
  2785. chipio_enable_clocks(codec);
  2786. - spec->dsp_state = DSP_DOWNLOADING;
  2787. - if (!ca0132_download_dsp_images(codec))
  2788. - spec->dsp_state = DSP_DOWNLOAD_FAILED;
  2789. - else
  2790. - spec->dsp_state = DSP_DOWNLOADED;
  2791. + if (spec->dsp_state != DSP_DOWNLOADED) {
  2792. + spec->dsp_state = DSP_DOWNLOADING;
  2793. - if (spec->dsp_state == DSP_DOWNLOADED)
  2794. + if (!ca0132_download_dsp_images(codec))
  2795. + spec->dsp_state = DSP_DOWNLOAD_FAILED;
  2796. + else
  2797. + spec->dsp_state = DSP_DOWNLOADED;
  2798. + }
  2799. +
  2800. + /* For codecs using alt functions, this is already done earlier */
  2801. + if (spec->dsp_state == DSP_DOWNLOADED && (!spec->use_alt_functions))
  2802. ca0132_set_dsp_msr(codec, true);
  2803. }
  2804. @@ -4454,6 +6695,10 @@
  2805. amic_callback);
  2806. snd_hda_jack_detect_enable_callback(codec, UNSOL_TAG_DSP,
  2807. ca0132_process_dsp_response);
  2808. + /* Front headphone jack detection */
  2809. + if (spec->use_alt_functions)
  2810. + snd_hda_jack_detect_enable_callback(codec,
  2811. + spec->unsol_tag_front_hp, hp_callback);
  2812. }
  2813. /*
  2814. @@ -4477,38 +6722,58 @@
  2815. };
  2816. /* Other verbs tables. Sends after DSP download. */
  2817. +
  2818. static struct hda_verb ca0132_init_verbs0[] = {
  2819. - /* chip init verbs */
  2820. - {0x15, 0x70D, 0xF0},
  2821. - {0x15, 0x70E, 0xFE},
  2822. - {0x15, 0x707, 0x75},
  2823. - {0x15, 0x707, 0xD3},
  2824. - {0x15, 0x707, 0x09},
  2825. - {0x15, 0x707, 0x53},
  2826. - {0x15, 0x707, 0xD4},
  2827. - {0x15, 0x707, 0xEF},
  2828. - {0x15, 0x707, 0x75},
  2829. - {0x15, 0x707, 0xD3},
  2830. - {0x15, 0x707, 0x09},
  2831. - {0x15, 0x707, 0x02},
  2832. - {0x15, 0x707, 0x37},
  2833. - {0x15, 0x707, 0x78},
  2834. - {0x15, 0x53C, 0xCE},
  2835. - {0x15, 0x575, 0xC9},
  2836. - {0x15, 0x53D, 0xCE},
  2837. - {0x15, 0x5B7, 0xC9},
  2838. - {0x15, 0x70D, 0xE8},
  2839. - {0x15, 0x70E, 0xFE},
  2840. - {0x15, 0x707, 0x02},
  2841. - {0x15, 0x707, 0x68},
  2842. - {0x15, 0x707, 0x62},
  2843. - {0x15, 0x53A, 0xCE},
  2844. - {0x15, 0x546, 0xC9},
  2845. - {0x15, 0x53B, 0xCE},
  2846. - {0x15, 0x5E8, 0xC9},
  2847. - {0x15, 0x717, 0x0D},
  2848. - {0x15, 0x718, 0x20},
  2849. - {}
  2850. + /* chip init verbs */
  2851. + {0x15, 0x70D, 0xF0},
  2852. + {0x15, 0x70E, 0xFE},
  2853. + {0x15, 0x707, 0x75},
  2854. + {0x15, 0x707, 0xD3},
  2855. + {0x15, 0x707, 0x09},
  2856. + {0x15, 0x707, 0x53},
  2857. + {0x15, 0x707, 0xD4},
  2858. + {0x15, 0x707, 0xEF},
  2859. + {0x15, 0x707, 0x75},
  2860. + {0x15, 0x707, 0xD3},
  2861. + {0x15, 0x707, 0x09},
  2862. + {0x15, 0x707, 0x02},
  2863. + {0x15, 0x707, 0x37},
  2864. + {0x15, 0x707, 0x78},
  2865. + {0x15, 0x53C, 0xCE},
  2866. + {0x15, 0x575, 0xC9},
  2867. + {0x15, 0x53D, 0xCE},
  2868. + {0x15, 0x5B7, 0xC9},
  2869. + {0x15, 0x70D, 0xE8},
  2870. + {0x15, 0x70E, 0xFE},
  2871. + {0x15, 0x707, 0x02},
  2872. + {0x15, 0x707, 0x68},
  2873. + {0x15, 0x707, 0x62},
  2874. + {0x15, 0x53A, 0xCE},
  2875. + {0x15, 0x546, 0xC9},
  2876. + {0x15, 0x53B, 0xCE},
  2877. + {0x15, 0x5E8, 0xC9},
  2878. + {}
  2879. +};
  2880. +
  2881. +/* Extra init verbs for SBZ */
  2882. +static struct hda_verb sbz_init_verbs[] = {
  2883. + {0x15, 0x70D, 0x20},
  2884. + {0x15, 0x70E, 0x19},
  2885. + {0x15, 0x707, 0x00},
  2886. + {0x15, 0x539, 0xCE},
  2887. + {0x15, 0x546, 0xC9},
  2888. + {0x15, 0x70D, 0xB7},
  2889. + {0x15, 0x70E, 0x09},
  2890. + {0x15, 0x707, 0x10},
  2891. + {0x15, 0x70D, 0xAF},
  2892. + {0x15, 0x70E, 0x09},
  2893. + {0x15, 0x707, 0x01},
  2894. + {0x15, 0x707, 0x05},
  2895. + {0x15, 0x70D, 0x73},
  2896. + {0x15, 0x70E, 0x09},
  2897. + {0x15, 0x707, 0x14},
  2898. + {0x15, 0x6FF, 0xC4},
  2899. + {}
  2900. };
  2901. static void ca0132_init_chip(struct hda_codec *codec)
  2902. @@ -4521,7 +6786,11 @@
  2903. mutex_init(&spec->chipio_mutex);
  2904. spec->cur_out_type = SPEAKER_OUT;
  2905. - spec->cur_mic_type = DIGITAL_MIC;
  2906. + if (!spec->use_alt_functions)
  2907. + spec->cur_mic_type = DIGITAL_MIC;
  2908. + else
  2909. + spec->cur_mic_type = REAR_MIC;
  2910. +
  2911. spec->cur_mic_boost = 0;
  2912. for (i = 0; i < VNODES_COUNT; i++) {
  2913. @@ -4539,6 +6808,15 @@
  2914. on = (unsigned int)ca0132_effects[i].reqs[0];
  2915. spec->effects_switch[i] = on ? 1 : 0;
  2916. }
  2917. + /*
  2918. + * Sets defaults for the effect slider controls, only for alternative
  2919. + * ca0132 codecs. Also sets x-bass crossover frequency to 80hz.
  2920. + */
  2921. + if (spec->use_alt_controls) {
  2922. + spec->xbass_xover_freq = 8;
  2923. + for(i = 0; i < EFFECT_LEVEL_SLIDERS; i++)
  2924. + spec->fx_ctl_val[i] = effect_slider_defaults[i];
  2925. + }
  2926. spec->voicefx_val = 0;
  2927. spec->effects_switch[PLAY_ENHANCEMENT - EFFECT_START_NID] = 1;
  2928. @@ -4549,6 +6827,129 @@
  2929. #endif
  2930. }
  2931. +/*
  2932. + * Recon3Di exit specific commands.
  2933. + */
  2934. +/* prevents popping noise on shutdown */
  2935. +static void r3di_gpio_shutdown(struct hda_codec *codec)
  2936. +{
  2937. + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0x00);
  2938. +}
  2939. +
  2940. +/*
  2941. + * Sound Blaster Z exit specific commands.
  2942. + */
  2943. +static void sbz_region2_exit(struct hda_codec *codec)
  2944. +{
  2945. + struct ca0132_spec *spec = codec->spec;
  2946. + unsigned int i;
  2947. +
  2948. + for(i = 0; i < 4; i++) {
  2949. + writeb(0x0, spec->mem_base + 0x100);
  2950. + }
  2951. + for(i = 0; i < 8; i++) {
  2952. + writeb(0xb3, spec->mem_base + 0x304);
  2953. + }
  2954. + /*
  2955. + * I believe these are GPIO, with the right most hex digit being the
  2956. + * gpio pin, and the second digit being on or off. We see this more in
  2957. + * the input/output select functions.
  2958. + */
  2959. + writew(0x0000, spec->mem_base + 0x320);
  2960. + writew(0x0001, spec->mem_base + 0x320);
  2961. + writew(0x0104, spec->mem_base + 0x320);
  2962. + writew(0x0005, spec->mem_base + 0x320);
  2963. + writew(0x0007, spec->mem_base + 0x320);
  2964. +
  2965. + return;
  2966. +}
  2967. +
  2968. +static void sbz_set_pin_ctl_default(struct hda_codec *codec)
  2969. +{
  2970. + hda_nid_t pins[5] = {0x0B, 0x0C, 0x0E, 0x12, 0x13};
  2971. + unsigned int i;
  2972. +
  2973. + snd_hda_codec_write(codec, 0x11, 0,
  2974. + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40);
  2975. +
  2976. + for(i = 0; i < 5; i++) {
  2977. + snd_hda_codec_write(codec, pins[i], 0,
  2978. + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00);
  2979. + }
  2980. +
  2981. + return;
  2982. +}
  2983. +
  2984. +static void sbz_clear_unsolicited(struct hda_codec *codec)
  2985. +{
  2986. + hda_nid_t pins[7] = {0x0B, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13};
  2987. + unsigned int i;
  2988. +
  2989. + for(i = 0; i < 7; i++) {
  2990. + snd_hda_codec_write(codec, pins[i], 0,
  2991. + AC_VERB_SET_UNSOLICITED_ENABLE, 0x00);
  2992. + }
  2993. +
  2994. + return;
  2995. +}
  2996. +
  2997. +/* On shutdown, sends commands in sets of three */
  2998. +static void sbz_gpio_shutdown_commands(struct hda_codec *codec, int dir,
  2999. + int mask, int data)
  3000. +{
  3001. + if (dir >= 0)
  3002. + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DIRECTION,
  3003. + dir);
  3004. + if (mask >= 0)
  3005. + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_MASK, mask);
  3006. +
  3007. + if (data >= 0)
  3008. + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, data);
  3009. +
  3010. + return;
  3011. +}
  3012. +
  3013. +static void sbz_exit_chip(struct hda_codec *codec)
  3014. +{
  3015. + chipio_set_stream_control(codec, 0x03, 0);
  3016. + chipio_set_stream_control(codec, 0x04, 0);
  3017. +
  3018. + /* Mess with GPIO */
  3019. + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, -1);
  3020. + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x05);
  3021. + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x01);
  3022. +
  3023. + chipio_set_stream_control(codec, 0x14, 0);
  3024. + chipio_set_stream_control(codec, 0x0C, 0);
  3025. +
  3026. + chipio_set_conn_rate(codec, 0x41, SR_192_000);
  3027. + chipio_set_conn_rate(codec, 0x91, SR_192_000);
  3028. +
  3029. + chipio_write(codec, 0x18a020, 0x00000083);
  3030. +
  3031. + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x03);
  3032. + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x07);
  3033. + sbz_gpio_shutdown_commands(codec, 0x07, 0x07, 0x06);
  3034. +
  3035. + chipio_set_stream_control(codec, 0x0C, 0);
  3036. +
  3037. + chipio_set_control_param(codec, 0x0D, 0x24);
  3038. +
  3039. + sbz_clear_unsolicited(codec);
  3040. + sbz_set_pin_ctl_default(codec);
  3041. +
  3042. + snd_hda_codec_write(codec, 0x0B, 0,
  3043. + AC_VERB_SET_EAPD_BTLENABLE, 0x00);
  3044. +
  3045. + if (dspload_is_loaded(codec))
  3046. + dsp_reset(codec);
  3047. +
  3048. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3049. + VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x00);
  3050. +
  3051. + sbz_region2_exit(codec);
  3052. +}
  3053. +
  3054. static void ca0132_exit_chip(struct hda_codec *codec)
  3055. {
  3056. /* put any chip cleanup stuffs here. */
  3057. @@ -4557,28 +6958,265 @@
  3058. dsp_reset(codec);
  3059. }
  3060. +/*
  3061. + * This fixes a problem that was hard to reproduce. Very rarely, I would
  3062. + * boot up, and there would be no sound, but the DSP indicated it had loaded
  3063. + * properly. I did a few memory dumps to see if anything was different, and
  3064. + * there were a few areas of memory uninitialized with a1a2a3a4. This function
  3065. + * checks if those areas are uninitialized, and if they are, it'll attempt to
  3066. + * reload the card 3 times. Usually it fixes by the second.
  3067. + */
  3068. +static void sbz_dsp_startup_check_entered(struct hda_codec *codec)
  3069. +{
  3070. + struct ca0132_spec *spec = codec->spec;
  3071. + unsigned int dsp_data_check[4];
  3072. + unsigned int cur_address = 0x390;
  3073. + unsigned int i;
  3074. + unsigned int failure = 0;
  3075. + unsigned int reload = 3;
  3076. +
  3077. + if (spec->startup_check_entered)
  3078. + return;
  3079. +
  3080. + spec->startup_check_entered = true;
  3081. +
  3082. + for (i = 0; i < 4; i++) {
  3083. + chipio_read(codec, cur_address, &dsp_data_check[i]);
  3084. + cur_address += 0x4;
  3085. + }
  3086. + for (i = 0; i < 4; i++) {
  3087. + if (dsp_data_check[i] == 0xa1a2a3a4)
  3088. + failure = 1;
  3089. + }
  3090. +
  3091. + codec_dbg(codec, "Startup Check: %d ", failure);
  3092. + if(failure)
  3093. + codec_info(codec, "DSP not initialized properly."
  3094. + "Attempting to fix.");
  3095. + /*
  3096. + * While the failure condition is true, and we haven't reached our
  3097. + * three reload limit, continue trying to reload the driver and
  3098. + * fix the issue.
  3099. + */
  3100. + while (failure && (reload != 0)) {
  3101. + codec_info(codec, "Reloading... Tries left: %d", reload);
  3102. + sbz_exit_chip(codec);
  3103. + spec->dsp_state = DSP_DOWNLOAD_INIT;
  3104. + codec->patch_ops.init(codec);
  3105. + failure = 0;
  3106. + for (i = 0; i < 4; i++) {
  3107. + chipio_read(codec, cur_address, &dsp_data_check[i]);
  3108. + cur_address += 0x4;
  3109. + }
  3110. + for (i = 0; i < 4; i++) {
  3111. + if (dsp_data_check[i] == 0xa1a2a3a4)
  3112. + failure = 1;
  3113. + }
  3114. + reload--;
  3115. + }
  3116. +
  3117. + if(!failure && reload < 3)
  3118. + codec_info(codec, "DSP fixed.");
  3119. +
  3120. + if (!failure)
  3121. + return;
  3122. +
  3123. + codec_info(codec, "DSP failed to initialize properly. Either try a full"
  3124. + "shutdown or a suspend to clear the internal memory.");
  3125. +}
  3126. +
  3127. +/*
  3128. + * This is for the extra volume verbs 0x797 (left) and 0x798 (right). These add
  3129. + * extra precision for decibel values. If you had the dB value in floating point
  3130. + * you would take the value after the decimal point, multiply by 64, and divide
  3131. + * by 2. So for 8.59, it's (59 * 64) / 100. Useful if someone wanted to
  3132. + * implement fixed point or floating point dB volumes. For now, I'll set them
  3133. + * to 0 just incase a value has lingered from a boot into Windows.
  3134. + */
  3135. +static void ca0132_alt_vol_setup(struct hda_codec *codec)
  3136. +{
  3137. +
  3138. + snd_hda_codec_write(codec, 0x02, 0, 0x797, 0x00);
  3139. + snd_hda_codec_write(codec, 0x02, 0, 0x798, 0x00);
  3140. + snd_hda_codec_write(codec, 0x03, 0, 0x797, 0x00);
  3141. + snd_hda_codec_write(codec, 0x03, 0, 0x798, 0x00);
  3142. + snd_hda_codec_write(codec, 0x04, 0, 0x797, 0x00);
  3143. + snd_hda_codec_write(codec, 0x04, 0, 0x798, 0x00);
  3144. + snd_hda_codec_write(codec, 0x07, 0, 0x797, 0x00);
  3145. + snd_hda_codec_write(codec, 0x07, 0, 0x798, 0x00);
  3146. +}
  3147. +
  3148. +/*
  3149. + * Extra commands that don't really fit anywhere else.
  3150. + */
  3151. +static void sbz_pre_dsp_setup(struct hda_codec *codec)
  3152. +{
  3153. + struct ca0132_spec *spec = codec->spec;
  3154. +
  3155. + writel(0x00820680, spec->mem_base + 0x01C);
  3156. + writel(0x00820680, spec->mem_base + 0x01C);
  3157. +
  3158. + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfc);
  3159. + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfd);
  3160. + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfe);
  3161. + snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xff);
  3162. +
  3163. + chipio_write(codec, 0x18b0a4, 0x000000c2);
  3164. +
  3165. + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x44);
  3166. +}
  3167. +
  3168. +/*
  3169. + * Extra commands that don't really fit anywhere else.
  3170. + */
  3171. +static void r3di_pre_dsp_setup(struct hda_codec *codec)
  3172. +{
  3173. + chipio_write(codec, 0x18b0a4, 0x000000c2);
  3174. +
  3175. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3176. + VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x1E);
  3177. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3178. + VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x1C);
  3179. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3180. + VENDOR_CHIPIO_8051_DATA_WRITE, 0x5B);
  3181. +
  3182. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3183. + VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x20);
  3184. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3185. + VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x19);
  3186. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3187. + VENDOR_CHIPIO_8051_DATA_WRITE, 0x00);
  3188. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3189. + VENDOR_CHIPIO_8051_DATA_WRITE, 0x40);
  3190. +
  3191. + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x04);
  3192. +}
  3193. +
  3194. +
  3195. +/*
  3196. + * These are sent before the DSP is downloaded. Not sure
  3197. + * what they do, or if they're necessary. Could possibly
  3198. + * be removed. Figure they're better to leave in.
  3199. + */
  3200. +static void sbz_region2_startup(struct hda_codec *codec)
  3201. +{
  3202. + struct ca0132_spec *spec = codec->spec;
  3203. +
  3204. + writel(0x00000000, spec->mem_base + 0x400);
  3205. + writel(0x00000000, spec->mem_base + 0x408);
  3206. + writel(0x00000000, spec->mem_base + 0x40C);
  3207. + writel(0x00880680, spec->mem_base + 0x01C);
  3208. + writel(0x00000083, spec->mem_base + 0xC0C);
  3209. + writel(0x00000030, spec->mem_base + 0xC00);
  3210. + writel(0x00000000, spec->mem_base + 0xC04);
  3211. + writel(0x00000003, spec->mem_base + 0xC0C);
  3212. + writel(0x00000003, spec->mem_base + 0xC0C);
  3213. + writel(0x00000003, spec->mem_base + 0xC0C);
  3214. + writel(0x00000003, spec->mem_base + 0xC0C);
  3215. + writel(0x000000C1, spec->mem_base + 0xC08);
  3216. + writel(0x000000F1, spec->mem_base + 0xC08);
  3217. + writel(0x00000001, spec->mem_base + 0xC08);
  3218. + writel(0x000000C7, spec->mem_base + 0xC08);
  3219. + writel(0x000000C1, spec->mem_base + 0xC08);
  3220. + writel(0x00000080, spec->mem_base + 0xC04);
  3221. +}
  3222. +
  3223. +/*
  3224. + * Extra init functions for alternative ca0132 codecs. Done
  3225. + * here so they don't clutter up the main ca0132_init function
  3226. + * anymore than they have to.
  3227. + */
  3228. +static void ca0132_alt_init(struct hda_codec *codec)
  3229. +{
  3230. + struct ca0132_spec *spec = codec->spec;
  3231. +
  3232. + ca0132_alt_vol_setup(codec);
  3233. +
  3234. + switch (spec->quirk) {
  3235. + case QUIRK_SBZ:
  3236. + codec_dbg(codec, "SBZ alt_init");
  3237. + ca0132_gpio_init(codec);
  3238. + sbz_pre_dsp_setup(codec);
  3239. + snd_hda_sequence_write(codec, spec->chip_init_verbs);
  3240. + snd_hda_sequence_write(codec, spec->sbz_init_verbs);
  3241. + break;
  3242. + case QUIRK_R3DI:
  3243. + codec_dbg(codec, "R3DI alt_init");
  3244. + ca0132_gpio_init(codec);
  3245. + ca0132_gpio_setup(codec);
  3246. + r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADING);
  3247. + r3di_pre_dsp_setup(codec);
  3248. + snd_hda_sequence_write(codec, spec->chip_init_verbs);
  3249. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x6FF, 0xC4);
  3250. + break;
  3251. + }
  3252. +}
  3253. +
  3254. static int ca0132_init(struct hda_codec *codec)
  3255. {
  3256. struct ca0132_spec *spec = codec->spec;
  3257. struct auto_pin_cfg *cfg = &spec->autocfg;
  3258. int i;
  3259. + bool dsp_loaded;
  3260. +
  3261. + /*
  3262. + * If the DSP is already downloaded, and init has been entered again,
  3263. + * there's only two reasons for it. One, the codec has awaken from a
  3264. + * suspended state, and in that case dspload_is_loaded will return
  3265. + * false, and the init will be ran again. The other reason it gets
  3266. + * re entered is on startup for some reason it triggers a suspend and
  3267. + * resume state. In this case, it will check if the DSP is downloaded,
  3268. + * and not run the init function again. For codecs using alt_functions,
  3269. + * it will check if the DSP is loaded properly.
  3270. + */
  3271. + if (spec->dsp_state == DSP_DOWNLOADED) {
  3272. + dsp_loaded = dspload_is_loaded(codec);
  3273. + if (dsp_loaded) {
  3274. + if (spec->quirk == QUIRK_SBZ)
  3275. + sbz_dsp_startup_check_entered(codec);
  3276. + return 0;
  3277. + } else {
  3278. + spec->dsp_reload = true;
  3279. + spec->dsp_state = DSP_DOWNLOAD_INIT;
  3280. + }
  3281. + }
  3282. if (spec->dsp_state != DSP_DOWNLOAD_FAILED)
  3283. spec->dsp_state = DSP_DOWNLOAD_INIT;
  3284. spec->curr_chip_addx = INVALID_CHIP_ADDRESS;
  3285. + if (spec->quirk == QUIRK_SBZ)
  3286. + sbz_region2_startup(codec);
  3287. +
  3288. snd_hda_power_up_pm(codec);
  3289. ca0132_init_unsol(codec);
  3290. -
  3291. ca0132_init_params(codec);
  3292. ca0132_init_flags(codec);
  3293. +
  3294. snd_hda_sequence_write(codec, spec->base_init_verbs);
  3295. +
  3296. + if (spec->quirk != QUIRK_NONE)
  3297. + ca0132_alt_init(codec);
  3298. +
  3299. ca0132_download_dsp(codec);
  3300. +
  3301. ca0132_refresh_widget_caps(codec);
  3302. - ca0132_setup_defaults(codec);
  3303. - ca0132_init_analog_mic2(codec);
  3304. - ca0132_init_dmic(codec);
  3305. +
  3306. + if (spec->quirk == QUIRK_SBZ)
  3307. + writew(0x0107, spec->mem_base + 0x320);
  3308. +
  3309. + switch (spec->quirk) {
  3310. + case QUIRK_R3DI:
  3311. + r3di_setup_defaults(codec);
  3312. + break;
  3313. + case QUIRK_NONE:
  3314. + case QUIRK_ALIENWARE:
  3315. + ca0132_setup_defaults(codec);
  3316. + ca0132_init_analog_mic2(codec);
  3317. + ca0132_init_dmic(codec);
  3318. + break;
  3319. + }
  3320. for (i = 0; i < spec->num_outputs; i++)
  3321. init_output(codec, spec->out_pins[i], spec->dacs[0]);
  3322. @@ -4590,14 +7228,45 @@
  3323. init_input(codec, cfg->dig_in_pin, spec->dig_in);
  3324. - snd_hda_sequence_write(codec, spec->chip_init_verbs);
  3325. - snd_hda_sequence_write(codec, spec->spec_init_verbs);
  3326. + if (!spec->use_alt_functions){
  3327. + snd_hda_sequence_write(codec, spec->chip_init_verbs);
  3328. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3329. + VENDOR_CHIPIO_PARAM_EX_ID_SET, 0x0D);
  3330. + snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
  3331. + VENDOR_CHIPIO_PARAM_EX_VALUE_SET, 0x20);
  3332. + }
  3333. - ca0132_select_out(codec);
  3334. - ca0132_select_mic(codec);
  3335. + if (spec->quirk == QUIRK_SBZ)
  3336. + ca0132_gpio_setup(codec);
  3337. +
  3338. + snd_hda_sequence_write(codec, spec->spec_init_verbs);
  3339. + switch (spec->quirk) {
  3340. + case QUIRK_SBZ:
  3341. + sbz_setup_defaults(codec);
  3342. + ca0132_alt_select_out(codec);
  3343. + ca0132_alt_select_in(codec);
  3344. + break;
  3345. + case QUIRK_R3DI:
  3346. + ca0132_alt_select_out(codec);
  3347. + ca0132_alt_select_in(codec);
  3348. + break;
  3349. + default:
  3350. + ca0132_select_out(codec);
  3351. + ca0132_select_mic(codec);
  3352. + break;
  3353. + }
  3354. snd_hda_jack_report_sync(codec);
  3355. + /*
  3356. + * Re set the PlayEnhancement switch on a resume event, because the
  3357. + * controls will not be reloaded.
  3358. + */
  3359. + if (spec->dsp_reload) {
  3360. + spec->dsp_reload = false;
  3361. + ca0132_pe_switch_set(codec);
  3362. + }
  3363. +
  3364. snd_hda_power_down_pm(codec);
  3365. return 0;
  3366. @@ -4609,19 +7278,40 @@
  3367. cancel_delayed_work_sync(&spec->unsol_hp_work);
  3368. snd_hda_power_up(codec);
  3369. - snd_hda_sequence_write(codec, spec->base_exit_verbs);
  3370. - ca0132_exit_chip(codec);
  3371. + switch (spec->quirk) {
  3372. + case QUIRK_SBZ:
  3373. + sbz_exit_chip(codec);
  3374. + /* unmap BAR region 2. */
  3375. + iounmap(spec->mem_base);
  3376. + break;
  3377. + case QUIRK_R3DI:
  3378. + r3di_gpio_shutdown(codec);
  3379. + snd_hda_sequence_write(codec, spec->base_exit_verbs);
  3380. + ca0132_exit_chip(codec);
  3381. + break;
  3382. + default:
  3383. + snd_hda_sequence_write(codec, spec->base_exit_verbs);
  3384. + ca0132_exit_chip(codec);
  3385. + break;
  3386. + }
  3387. snd_hda_power_down(codec);
  3388. kfree(spec->spec_init_verbs);
  3389. kfree(codec->spec);
  3390. }
  3391. +static void ca0132_reboot_notify(struct hda_codec *codec)
  3392. +{
  3393. + codec->patch_ops.free(codec);
  3394. + return;
  3395. +}
  3396. +
  3397. static const struct hda_codec_ops ca0132_patch_ops = {
  3398. .build_controls = ca0132_build_controls,
  3399. .build_pcms = ca0132_build_pcms,
  3400. .init = ca0132_init,
  3401. .free = ca0132_free,
  3402. .unsol_event = snd_hda_jack_unsol_event,
  3403. + .reboot_notify = ca0132_reboot_notify,
  3404. };
  3405. static void ca0132_config(struct hda_codec *codec)
  3406. @@ -4635,9 +7325,14 @@
  3407. spec->multiout.dac_nids = spec->dacs;
  3408. spec->multiout.num_dacs = 3;
  3409. - spec->multiout.max_channels = 2;
  3410. - if (spec->quirk == QUIRK_ALIENWARE) {
  3411. + if (!spec->use_alt_functions)
  3412. + spec->multiout.max_channels = 2;
  3413. + else
  3414. + spec->multiout.max_channels = 6;
  3415. +
  3416. + switch (spec->quirk) {
  3417. + case QUIRK_ALIENWARE:
  3418. codec_dbg(codec, "ca0132_config: QUIRK_ALIENWARE applied.\n");
  3419. snd_hda_apply_pincfgs(codec, alienware_pincfgs);
  3420. @@ -4657,7 +7352,71 @@
  3421. spec->input_pins[2] = 0x13;
  3422. spec->shared_mic_nid = 0x7;
  3423. spec->unsol_tag_amic1 = 0x11;
  3424. - } else {
  3425. + break;
  3426. + case QUIRK_SBZ:
  3427. + codec_dbg(codec, "ca0132_config: QUIRK_SBZ applied.\n");
  3428. + snd_hda_apply_pincfgs(codec, sbz_pincfgs);
  3429. +
  3430. + spec->num_outputs = 2;
  3431. + spec->out_pins[0] = 0x0B; /* Line out */
  3432. + spec->out_pins[1] = 0x0F; /* Rear headphone out */
  3433. + spec->out_pins[2] = 0x10; /* Front Headphone / Center/LFE*/
  3434. + spec->out_pins[3] = 0x11; /* Rear surround */
  3435. + spec->shared_out_nid = 0x2;
  3436. + spec->unsol_tag_hp = spec->out_pins[1];
  3437. + spec->unsol_tag_front_hp = spec->out_pins[2];
  3438. +
  3439. + spec->adcs[0] = 0x7; /* Rear Mic / Line-in */
  3440. + spec->adcs[1] = 0x8; /* Front Mic, but only if no DSP */
  3441. + spec->adcs[2] = 0xa; /* what u hear */
  3442. +
  3443. + spec->num_inputs = 2;
  3444. + spec->input_pins[0] = 0x12; /* Rear Mic / Line-in */
  3445. + spec->input_pins[1] = 0x13; /* What U Hear */
  3446. + spec->shared_mic_nid = 0x7;
  3447. + spec->unsol_tag_amic1 = spec->input_pins[0];
  3448. +
  3449. + /* SPDIF I/O */
  3450. + spec->dig_out = 0x05;
  3451. + spec->multiout.dig_out_nid = spec->dig_out;
  3452. + cfg->dig_out_pins[0] = 0x0c;
  3453. + cfg->dig_outs = 1;
  3454. + cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF;
  3455. + spec->dig_in = 0x09;
  3456. + cfg->dig_in_pin = 0x0e;
  3457. + cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
  3458. + break;
  3459. + case QUIRK_R3DI:
  3460. + codec_dbg(codec, "ca0132_config: QUIRK_R3DI applied.\n");
  3461. + snd_hda_apply_pincfgs(codec, r3di_pincfgs);
  3462. +
  3463. + spec->num_outputs = 2;
  3464. + spec->out_pins[0] = 0x0B; /* Line out */
  3465. + spec->out_pins[1] = 0x0F; /* Rear headphone out */
  3466. + spec->out_pins[2] = 0x10; /* Front Headphone / Center/LFE*/
  3467. + spec->out_pins[3] = 0x11; /* Rear surround */
  3468. + spec->shared_out_nid = 0x2;
  3469. + spec->unsol_tag_hp = spec->out_pins[1];
  3470. + spec->unsol_tag_front_hp = spec->out_pins[2];
  3471. +
  3472. + spec->adcs[0] = 0x07; /* Rear Mic / Line-in */
  3473. + spec->adcs[1] = 0x08; /* Front Mic, but only if no DSP */
  3474. + spec->adcs[2] = 0x0a; /* what u hear */
  3475. +
  3476. + spec->num_inputs = 2;
  3477. + spec->input_pins[0] = 0x12; /* Rear Mic / Line-in */
  3478. + spec->input_pins[1] = 0x13; /* What U Hear */
  3479. + spec->shared_mic_nid = 0x7;
  3480. + spec->unsol_tag_amic1 = spec->input_pins[0];
  3481. +
  3482. + /* SPDIF I/O */
  3483. + spec->dig_out = 0x05;
  3484. + spec->multiout.dig_out_nid = spec->dig_out;
  3485. + cfg->dig_out_pins[0] = 0x0c;
  3486. + cfg->dig_outs = 1;
  3487. + cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF;
  3488. + break;
  3489. + default:
  3490. spec->num_outputs = 2;
  3491. spec->out_pins[0] = 0x0b; /* speaker out */
  3492. spec->out_pins[1] = 0x10; /* headphone out */
  3493. @@ -4684,6 +7443,7 @@
  3494. spec->dig_in = 0x09;
  3495. cfg->dig_in_pin = 0x0e;
  3496. cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
  3497. + break;
  3498. }
  3499. }
  3500. @@ -4694,6 +7454,8 @@
  3501. struct ca0132_spec *spec = codec->spec;
  3502. spec->chip_init_verbs = ca0132_init_verbs0;
  3503. + if (spec->quirk == QUIRK_SBZ)
  3504. + spec->sbz_init_verbs = sbz_init_verbs;
  3505. spec->spec_init_verbs = kzalloc(sizeof(struct hda_verb) * NUM_SPEC_VERBS, GFP_KERNEL);
  3506. if (!spec->spec_init_verbs)
  3507. return -ENOMEM;
  3508. @@ -4757,9 +7519,46 @@
  3509. else
  3510. spec->quirk = QUIRK_NONE;
  3511. + /* Setup BAR Region 2 for Sound Blaster Z */
  3512. + if (spec->quirk == QUIRK_SBZ) {
  3513. + spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20);
  3514. + if (spec->mem_base == NULL) {
  3515. + codec_dbg(codec, "pci_iomap failed!");
  3516. + codec_dbg(codec, "perhaps this is not an SBZ?");
  3517. + spec->quirk = QUIRK_NONE;
  3518. + }
  3519. + }
  3520. +
  3521. spec->dsp_state = DSP_DOWNLOAD_INIT;
  3522. spec->num_mixers = 1;
  3523. - spec->mixers[0] = ca0132_mixer;
  3524. +
  3525. + /* Set which mixers each quirk uses. */
  3526. + switch (spec->quirk) {
  3527. + case QUIRK_SBZ:
  3528. + spec->mixers[0] = sbz_mixer;
  3529. + snd_hda_codec_set_name(codec, "Sound Blaster Z");
  3530. + break;
  3531. + case QUIRK_R3DI:
  3532. + spec->mixers[0] = r3di_mixer;
  3533. + snd_hda_codec_set_name(codec, "Recon3Di");
  3534. + break;
  3535. + default:
  3536. + spec->mixers[0] = ca0132_mixer;
  3537. + break;
  3538. + }
  3539. +
  3540. + /* Setup whether or not to use alt functions/controls */
  3541. + switch (spec->quirk) {
  3542. + case QUIRK_SBZ:
  3543. + case QUIRK_R3DI:
  3544. + spec->use_alt_controls = true;
  3545. + spec->use_alt_functions = true;
  3546. + break;
  3547. + default:
  3548. + spec->use_alt_controls = false;
  3549. + spec->use_alt_functions = false;
  3550. + break;
  3551. + }
  3552. spec->base_init_verbs = ca0132_base_init_verbs;
  3553. spec->base_exit_verbs = ca0132_base_exit_verbs;
  3554.