void ps3av_cmd_set_audio_mode()

in ps3av_cmd.c [666:781]


void ps3av_cmd_set_audio_mode(struct ps3av_pkt_audio_mode *audio, u32 avport,
			      u32 ch, u32 fs, u32 word_bits, u32 format,
			      u32 source)
{
	int spdif_through;
	int i;

	if (!(ch | fs | format | word_bits | source)) {
		ch = PS3AV_CMD_AUDIO_NUM_OF_CH_2;
		fs = PS3AV_CMD_AUDIO_FS_48K;
		word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16;
		format = PS3AV_CMD_AUDIO_FORMAT_PCM;
		source = PS3AV_CMD_AUDIO_SOURCE_SERIAL;
	}

	/* audio mode */
	memset(audio, 0, sizeof(*audio));
	ps3av_set_hdr(PS3AV_CID_AUDIO_MODE, sizeof(*audio), &audio->send_hdr);

	audio->avport = (u8) avport;
	audio->mask = 0x0FFF;	/* XXX set all */
	audio->audio_num_of_ch = ch;
	audio->audio_fs = fs;
	audio->audio_word_bits = word_bits;
	audio->audio_format = format;
	audio->audio_source = source;

	switch (ch) {
	case PS3AV_CMD_AUDIO_NUM_OF_CH_8:
		audio->audio_enable[3] = 1;
		fallthrough;
	case PS3AV_CMD_AUDIO_NUM_OF_CH_6:
		audio->audio_enable[2] = 1;
		audio->audio_enable[1] = 1;
		fallthrough;
	case PS3AV_CMD_AUDIO_NUM_OF_CH_2:
	default:
		audio->audio_enable[0] = 1;
	}

	/* audio swap L/R */
	for (i = 0; i < 4; i++)
		audio->audio_swap[i] = PS3AV_CMD_AUDIO_SWAP_0;	/* no swap */

	/* audio serial input mapping */
	audio->audio_map[0] = PS3AV_CMD_AUDIO_MAP_OUTPUT_0;
	audio->audio_map[1] = PS3AV_CMD_AUDIO_MAP_OUTPUT_1;
	audio->audio_map[2] = PS3AV_CMD_AUDIO_MAP_OUTPUT_2;
	audio->audio_map[3] = PS3AV_CMD_AUDIO_MAP_OUTPUT_3;

	/* audio speaker layout */
	if (avport == PS3AV_CMD_AVPORT_HDMI_0 ||
	    avport == PS3AV_CMD_AVPORT_HDMI_1) {
		switch (ch) {
		case PS3AV_CMD_AUDIO_NUM_OF_CH_8:
			audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_8CH;
			break;
		case PS3AV_CMD_AUDIO_NUM_OF_CH_6:
			audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_6CH;
			break;
		case PS3AV_CMD_AUDIO_NUM_OF_CH_2:
		default:
			audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH;
			break;
		}
	} else {
		audio->audio_layout = PS3AV_CMD_AUDIO_LAYOUT_2CH;
	}

	/* audio downmix permission */
	audio->audio_downmix = PS3AV_CMD_AUDIO_DOWNMIX_PERMITTED;
	/* audio downmix level shift (0:0dB to 15:15dB) */
	audio->audio_downmix_level = 0;	/* 0dB */

	/* set ch status */
	for (i = 0; i < 8; i++)
		audio->audio_cs_info[i] = ps3av_mode_cs_info[i];

	switch (fs) {
	case PS3AV_CMD_AUDIO_FS_44K:
		audio->audio_cs_info[3] &= ~CS_MASK;
		audio->audio_cs_info[3] |= CS_44;
		break;
	case PS3AV_CMD_AUDIO_FS_88K:
		audio->audio_cs_info[3] &= ~CS_MASK;
		audio->audio_cs_info[3] |= CS_88;
		break;
	case PS3AV_CMD_AUDIO_FS_96K:
		audio->audio_cs_info[3] &= ~CS_MASK;
		audio->audio_cs_info[3] |= CS_96;
		break;
	case PS3AV_CMD_AUDIO_FS_176K:
		audio->audio_cs_info[3] &= ~CS_MASK;
		audio->audio_cs_info[3] |= CS_176;
		break;
	case PS3AV_CMD_AUDIO_FS_192K:
		audio->audio_cs_info[3] &= ~CS_MASK;
		audio->audio_cs_info[3] |= CS_192;
		break;
	default:
		break;
	}

	/* non-audio bit */
	spdif_through = audio->audio_cs_info[0] & 0x02;

	/* pass through setting */
	if (spdif_through &&
	    (avport == PS3AV_CMD_AVPORT_SPDIF_0 ||
	     avport == PS3AV_CMD_AVPORT_SPDIF_1 ||
	     avport == PS3AV_CMD_AVPORT_HDMI_0 ||
	     avport == PS3AV_CMD_AVPORT_HDMI_1)) {
		audio->audio_word_bits = PS3AV_CMD_AUDIO_WORD_BITS_16;
		audio->audio_format = PS3AV_CMD_AUDIO_FORMAT_BITSTREAM;
	}
}