Explorar o código

V4L/DVB (3246): Use VIDIOC_S_AUDIO instead of AUDC_SET_INPUT in cs53l32a

- Replace AUDC_SET_INPUT with VIDIOC_S_AUDIO.
- Added V4L2_CID_AUDIO_MUTE.
- Minimum volume is -96 dB, not -90.
- Show volume in VIDIOC_LOG_STATUS.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Hans Verkuil %!s(int64=19) %!d(string=hai) anos
pai
achega
936053516a
Modificáronse 1 ficheiros con 37 adicións e 28 borrados
  1. 37 28
      drivers/media/video/cs53l32a.c

+ 37 - 28
drivers/media/video/cs53l32a.c

@@ -74,50 +74,59 @@ static int cs53l32a_read(struct i2c_client *client, u8 reg)
 static int cs53l32a_command(struct i2c_client *client, unsigned int cmd,
 			    void *arg)
 {
-	int *input = arg;
+	struct v4l2_audio *input = arg;
+	struct v4l2_control *ctrl = arg;
 
 	switch (cmd) {
-	case AUDC_SET_INPUT:
-		switch (*input) {
-		case AUDIO_TUNER:
-			cs53l32a_write(client, 0x01, 0x01);
-			break;
-		case AUDIO_EXTERN:
-			cs53l32a_write(client, 0x01, 0x21);
-			break;
-		case AUDIO_MUTE:
-			cs53l32a_write(client, 0x03, 0xF0);
-			break;
-		case AUDIO_UNMUTE:
-			cs53l32a_write(client, 0x03, 0x30);
-			break;
-		default:
-			cs53l32a_err("Invalid input %d.\n", *input);
+	case VIDIOC_S_AUDIO:
+		/* There are 2 physical inputs, but the second input can be
+		   placed in two modes, the first mode bypasses the PGA (gain),
+		   the second goes through the PGA. Hence there are three
+		   possible inputs to choose from. */
+		if (input->index > 2) {
+			cs53l32a_err("Invalid input %d.\n", input->index);
 			return -EINVAL;
 		}
+		cs53l32a_write(client, 0x01, 0x01 + (input->index << 4));
+		break;
+
+	case VIDIOC_G_AUDIO:
+		memset(input, 0, sizeof(*input));
+		input->index = (cs53l32a_read(client, 0x01) >> 4) & 3;
+		break;
+
+	case VIDIOC_G_CTRL:
+		if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
+			ctrl->value = (cs53l32a_read(client, 0x03) & 0xc0) != 0;
+			break;
+		}
+		if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
+			return -EINVAL;
+		ctrl->value = (s8)cs53l32a_read(client, 0x04);
 		break;
 
 	case VIDIOC_S_CTRL:
-		{
-			struct v4l2_control *ctrl = arg;
-
-			if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
-				return -EINVAL;
-			if (ctrl->value > 12 || ctrl->value < -90)
-				return -EINVAL;
-			cs53l32a_write(client, 0x04, (u8) ctrl->value);
-			cs53l32a_write(client, 0x05, (u8) ctrl->value);
+		if (ctrl->id == V4L2_CID_AUDIO_MUTE) {
+			cs53l32a_write(client, 0x03, ctrl->value ? 0xf0 : 0x30);
 			break;
 		}
+		if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
+			return -EINVAL;
+		if (ctrl->value > 12 || ctrl->value < -96)
+			return -EINVAL;
+		cs53l32a_write(client, 0x04, (u8) ctrl->value);
+		cs53l32a_write(client, 0x05, (u8) ctrl->value);
+		break;
 
 	case VIDIOC_LOG_STATUS:
 		{
 			u8 v = cs53l32a_read(client, 0x01);
 			u8 m = cs53l32a_read(client, 0x03);
+			s8 vol = cs53l32a_read(client, 0x04);
 
-			cs53l32a_info("Input: %s%s\n",
-				      v == 0x21 ? "external line in" : "tuner",
+			cs53l32a_info("Input:  %d%s\n", (v >> 4) & 3,
 				      (m & 0xC0) ? " (muted)" : "");
+			cs53l32a_info("Volume: %d dB\n", vol);
 			break;
 		}