Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

media: adv7180: Power down decoder when configuring the device

Some variants of the chip (ADV7180) have it's decoder powered up after
reset, while others (ADV7280, ADV7281, ADV7282, ADV7283) have it powered
down.

This is tracked by the feature flag ADV7180_FLAG_RESET_POWERED. At probe
this flag is used to initialize the state variable powered which keeps
track of if the decoder is powered on, or off, for the resume callback.

This however misses that the decoder needs to be powered off for some
configuration of the device to take hold. So for devices where it's left
on (ADV7180) the format configuration at probe time have little effect.
This worked as the .set_fmt callback powers down the decoder, updates
the format, and powers back on the decoder.

Before moving all configuration to .s_stream this needs to be fixed.
Instead of tracking if the decoder is powered on or off, use the
flag to determine if needs to be powered down after a reset to do the
configuration.

To keep the behavior consistent with the currents implementation switch
the decoder back on for devices where this is the reset behavior. The
primary reason for this is that if not done the first 35+ frames or so
of the capture session is garbage.

To keep the support of starting the decoder when resuming from sleep on
devices where the reset behavior is to start with the decoder powered
off, use the state variable streaming. If it is set the decoder was
powered on when the system suspended so we know to start it again when
resuming.

Signed-off-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
[hverkuil: fix typo in comment: where -> were]

authored by

Niklas Söderlund and committed by
Hans Verkuil
f55cd379 dc12a27c

+22 -12
+22 -12
drivers/media/i2c/adv7180.c
··· 214 214 struct gpio_desc *pwdn_gpio; 215 215 struct gpio_desc *rst_gpio; 216 216 v4l2_std_id curr_norm; 217 - bool powered; 218 217 bool streaming; 219 218 u8 input; 220 219 ··· 555 556 return ret; 556 557 557 558 ret = adv7180_set_power(state, on); 558 - if (ret == 0) 559 - state->powered = on; 560 559 561 560 mutex_unlock(&state->mutex); 562 561 return ret; ··· 884 887 adv7180_write(state, ADV7180_REG_PWR_MAN, ADV7180_PWR_MAN_RES); 885 888 usleep_range(5000, 10000); 886 889 890 + /* 891 + * If the devices decoder is power on after reset, power off so the 892 + * device can be configured. 893 + */ 894 + if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED) 895 + adv7180_set_power(state, false); 896 + 887 897 ret = state->chip_info->init(state); 888 898 if (ret) 889 899 return ret; ··· 930 926 if (ret < 0) 931 927 return ret; 932 928 } 929 + 930 + /* 931 + * If the devices decoder is power on after reset, restore the power 932 + * after configuration. This is to preserve the behavior of the driver, 933 + * not doing this result in the first 35+ frames captured being garbage. 934 + */ 935 + if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED) 936 + adv7180_set_power(state, true); 933 937 934 938 return 0; 935 939 } ··· 1469 1457 state->irq = client->irq; 1470 1458 mutex_init(&state->mutex); 1471 1459 state->curr_norm = V4L2_STD_NTSC; 1472 - if (state->chip_info->flags & ADV7180_FLAG_RESET_POWERED) 1473 - state->powered = true; 1474 - else 1475 - state->powered = false; 1460 + 1476 1461 state->input = 0; 1477 1462 sd = &state->sd; 1478 1463 v4l2_i2c_subdev_init(sd, client, &adv7180_ops); ··· 1577 1568 if (ret < 0) 1578 1569 return ret; 1579 1570 1580 - guard(mutex)(&state->mutex); 1581 - 1582 - ret = adv7180_set_power(state, state->powered); 1583 - if (ret) 1584 - return ret; 1571 + /* If we were streaming when suspending, start decoder. */ 1572 + if (state->streaming) { 1573 + ret = adv7180_set_power(state, true); 1574 + if (ret) 1575 + return ret; 1576 + } 1585 1577 1586 1578 return 0; 1587 1579 }