2019-05-19 15:51:31 +02:00
// SPDX-License-Identifier: GPL-2.0-or-later
2012-09-01 21:09:21 -03:00
/*
* Elonics E4000 silicon tuner driver
*
* Copyright ( C ) 2012 Antti Palosaari < crope @ iki . fi >
*/
# include "e4000_priv.h"
2015-05-12 14:26:07 -03:00
static int e4000_init ( struct e4000_dev * dev )
2012-09-01 21:09:21 -03:00
{
2015-04-21 17:13:39 -03:00
struct i2c_client * client = dev - > client ;
2012-09-01 21:09:21 -03:00
int ret ;
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev , " \n " ) ;
2012-09-01 21:09:21 -03:00
/* reset */
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x00 , 0x01 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
/* disable output clock */
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x06 , 0x00 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x7a , 0x96 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
/* configure gains */
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x7e , " \x01 \xfe " , 2 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x82 , 0x00 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x24 , 0x05 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x87 , " \x20 \x01 " , 2 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x9f , " \x7f \x07 " , 2 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
/* DC offset control */
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x2d , 0x1f ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2013-07-24 02:04:12 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x70 , " \x01 \x01 " , 2 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
/* gain control */
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x1a , 0x17 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x1f , 0x1a ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
dev - > active = true ;
2012-09-01 21:09:21 -03:00
2015-04-21 17:13:39 -03:00
return 0 ;
err :
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2012-09-01 21:09:21 -03:00
return ret ;
}
2015-05-12 14:26:07 -03:00
static int e4000_sleep ( struct e4000_dev * dev )
2012-09-01 21:09:21 -03:00
{
2015-04-21 17:13:39 -03:00
struct i2c_client * client = dev - > client ;
2012-09-01 21:09:21 -03:00
int ret ;
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev , " \n " ) ;
2012-09-01 21:09:21 -03:00
2015-04-21 17:13:39 -03:00
dev - > active = false ;
2014-02-07 02:55:57 -03:00
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x00 , 0x00 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
return 0 ;
err :
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2012-09-01 21:09:21 -03:00
return ret ;
}
2015-05-12 14:26:07 -03:00
static int e4000_set_params ( struct e4000_dev * dev )
2012-09-01 21:09:21 -03:00
{
2015-04-21 17:13:39 -03:00
struct i2c_client * client = dev - > client ;
2015-04-21 21:18:45 -03:00
int ret , i ;
unsigned int div_n , k , k_cw , div_out ;
2014-01-27 03:13:19 -03:00
u64 f_vco ;
2013-07-24 02:04:12 -03:00
u8 buf [ 5 ] , i_data [ 4 ] , q_data [ 4 ] ;
2012-09-01 21:09:21 -03:00
2015-05-12 14:26:07 -03:00
if ( ! dev - > active ) {
dev_dbg ( & client - > dev , " tuner is sleeping \n " ) ;
return 0 ;
}
2012-09-01 21:09:21 -03:00
/* gain control manual */
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x1a , 0x00 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 21:18:45 -03:00
/*
* Fractional - N synthesizer
*
* + - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
* v |
* Fref + - - - - + + - - - - - - - + + - - - - - - + + - - - +
* - - - - - - > | PD | - - > | VCO | - - - - - - > | / N . F | < - - | K |
* + - - - - + + - - - - - - - + + - - - - - - + + - - - +
* |
* |
* v
* + - - - - - - - + Fout
* | / Rout | - - - - - - >
* + - - - - - - - +
*/
2012-09-01 21:09:21 -03:00
for ( i = 0 ; i < ARRAY_SIZE ( e4000_pll_lut ) ; i + + ) {
2015-05-12 14:26:07 -03:00
if ( dev - > f_frequency < = e4000_pll_lut [ i ] . freq )
2012-09-01 21:09:21 -03:00
break ;
}
2013-12-29 19:47:35 -03:00
if ( i = = ARRAY_SIZE ( e4000_pll_lut ) ) {
ret = - EINVAL ;
2012-09-01 21:09:21 -03:00
goto err ;
2013-12-29 19:47:35 -03:00
}
2012-09-01 21:09:21 -03:00
2015-04-21 17:13:39 -03:00
# define F_REF dev->clk
2015-04-21 21:18:45 -03:00
div_out = e4000_pll_lut [ i ] . div_out ;
2015-05-12 14:26:07 -03:00
f_vco = ( u64 ) dev - > f_frequency * div_out ;
2015-04-21 21:18:45 -03:00
/* calculate PLL integer and fractional control word */
div_n = div_u64_rem ( f_vco , F_REF , & k ) ;
k_cw = div_u64 ( ( u64 ) k * 0x10000 , F_REF ) ;
2012-09-01 21:09:21 -03:00
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev ,
2015-05-12 14:26:07 -03:00
" frequency=%u bandwidth=%u f_vco=%llu F_REF=%u div_n=%u k=%u k_cw=%04x div_out=%u \n " ,
dev - > f_frequency , dev - > f_bandwidth , f_vco , F_REF , div_n , k ,
k_cw , div_out ) ;
2012-09-01 21:09:21 -03:00
2015-04-21 21:18:45 -03:00
buf [ 0 ] = div_n ;
buf [ 1 ] = ( k_cw > > 0 ) & 0xff ;
buf [ 2 ] = ( k_cw > > 8 ) & 0xff ;
buf [ 3 ] = 0x00 ;
buf [ 4 ] = e4000_pll_lut [ i ] . div_out_reg ;
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x09 , buf , 5 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
/* LNA filter (RF filter) */
for ( i = 0 ; i < ARRAY_SIZE ( e400_lna_filter_lut ) ; i + + ) {
2015-05-12 14:26:07 -03:00
if ( dev - > f_frequency < = e400_lna_filter_lut [ i ] . freq )
2012-09-01 21:09:21 -03:00
break ;
}
2013-12-29 19:47:35 -03:00
if ( i = = ARRAY_SIZE ( e400_lna_filter_lut ) ) {
ret = - EINVAL ;
2012-09-01 21:09:21 -03:00
goto err ;
2013-12-29 19:47:35 -03:00
}
2012-09-01 21:09:21 -03:00
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x10 , e400_lna_filter_lut [ i ] . val ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
/* IF filters */
for ( i = 0 ; i < ARRAY_SIZE ( e4000_if_filter_lut ) ; i + + ) {
2015-05-12 14:26:07 -03:00
if ( dev - > f_bandwidth < = e4000_if_filter_lut [ i ] . freq )
2012-09-01 21:09:21 -03:00
break ;
}
2013-12-29 19:47:35 -03:00
if ( i = = ARRAY_SIZE ( e4000_if_filter_lut ) ) {
ret = - EINVAL ;
2012-09-01 21:09:21 -03:00
goto err ;
2013-12-29 19:47:35 -03:00
}
2012-09-01 21:09:21 -03:00
buf [ 0 ] = e4000_if_filter_lut [ i ] . reg11_val ;
buf [ 1 ] = e4000_if_filter_lut [ i ] . reg12_val ;
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x11 , buf , 2 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
/* frequency band */
for ( i = 0 ; i < ARRAY_SIZE ( e4000_band_lut ) ; i + + ) {
2015-05-12 14:26:07 -03:00
if ( dev - > f_frequency < = e4000_band_lut [ i ] . freq )
2012-09-01 21:09:21 -03:00
break ;
}
2013-12-29 19:47:35 -03:00
if ( i = = ARRAY_SIZE ( e4000_band_lut ) ) {
ret = - EINVAL ;
2012-09-01 21:09:21 -03:00
goto err ;
2013-12-29 19:47:35 -03:00
}
2012-09-01 21:09:21 -03:00
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x07 , e4000_band_lut [ i ] . reg07_val ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x78 , e4000_band_lut [ i ] . reg78_val ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2013-07-24 02:04:12 -03:00
/* DC offset */
for ( i = 0 ; i < 4 ; i + + ) {
if ( i = = 0 )
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x15 , " \x00 \x7e \x24 " , 3 ) ;
2013-07-24 02:04:12 -03:00
else if ( i = = 1 )
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x15 , " \x00 \x7f " , 2 ) ;
2013-07-24 02:04:12 -03:00
else if ( i = = 2 )
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x15 , " \x01 " , 1 ) ;
2013-07-24 02:04:12 -03:00
else
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x16 , " \x7e " , 1 ) ;
2013-07-24 02:04:12 -03:00
2014-02-10 22:52:51 -03:00
if ( ret )
2013-07-24 02:04:12 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x29 , 0x01 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2013-07-24 02:04:12 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_read ( dev - > regmap , 0x2a , buf , 3 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2013-07-24 02:04:12 -03:00
goto err ;
i_data [ i ] = ( ( ( buf [ 2 ] > > 0 ) & 0x3 ) < < 6 ) | ( buf [ 0 ] & 0x3f ) ;
q_data [ i ] = ( ( ( buf [ 2 ] > > 4 ) & 0x3 ) < < 6 ) | ( buf [ 1 ] & 0x3f ) ;
}
2013-07-24 18:33:51 -03:00
swap ( q_data [ 2 ] , q_data [ 3 ] ) ;
swap ( i_data [ 2 ] , i_data [ 3 ] ) ;
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x50 , q_data , 4 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2013-07-24 02:04:12 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
ret = regmap_bulk_write ( dev - > regmap , 0x60 , i_data , 4 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2013-07-24 02:04:12 -03:00
goto err ;
2012-09-01 21:09:21 -03:00
/* gain control auto */
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x1a , 0x17 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2012-09-01 21:09:21 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
return 0 ;
err :
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2012-09-01 21:09:21 -03:00
return ret ;
}
2015-05-12 14:26:07 -03:00
/*
* V4L2 API
*/
media: Kconfig: cleanup VIDEO_DEV dependencies
media Kconfig has two entries associated to V4L API:
VIDEO_DEV and VIDEO_V4L2.
On Kernel 2.6.x, there were two V4L APIs, each one with its own flag.
VIDEO_DEV were meant to:
1) enable Video4Linux and make its Kconfig options to appear;
2) it makes the Kernel build the V4L core.
while VIDEO_V4L2 where used to distinguish between drivers that
implement the newer API and drivers that implemented the former one.
With time, such meaning changed, specially after the removal of
all V4L version 1 drivers.
At the current implementation, VIDEO_DEV only does (1): it enables
the media options related to V4L, that now has:
menu "Video4Linux options"
visible if VIDEO_DEV
source "drivers/media/v4l2-core/Kconfig"
endmenu
but it doesn't affect anymore the V4L core drivers.
The rationale is that the V4L2 core has a "soft" dependency
at the I2C bus, and now requires to select a number of other
Kconfig options:
config VIDEO_V4L2
tristate
depends on (I2C || I2C=n) && VIDEO_DEV
select RATIONAL
select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE
default (I2C || I2C=n) && VIDEO_DEV
In the past, merging them would be tricky, but it seems that it is now
possible to merge those symbols, in order to simplify V4L dependencies.
Let's keep VIDEO_DEV, as this one is used on some make *defconfig
configurations.
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> # for meson-vdec & meson-ge2d
Acked-by: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
Acked-by: Łukasz Stelmach <l.stelmach@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2022-03-13 07:25:46 +01:00
# if IS_ENABLED(CONFIG_VIDEO_DEV)
2015-05-12 14:26:07 -03:00
static const struct v4l2_frequency_band bands [ ] = {
{
. type = V4L2_TUNER_RF ,
. index = 0 ,
. capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS ,
. rangelow = 59000000 ,
. rangehigh = 1105000000 ,
} ,
{
. type = V4L2_TUNER_RF ,
. index = 1 ,
. capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS ,
. rangelow = 1249000000 ,
2015-05-22 04:39:54 -03:00
. rangehigh = 2208000000UL ,
2015-05-12 14:26:07 -03:00
} ,
} ;
static inline struct e4000_dev * e4000_subdev_to_dev ( struct v4l2_subdev * sd )
2012-09-01 21:09:21 -03:00
{
2015-05-12 14:26:07 -03:00
return container_of ( sd , struct e4000_dev , sd ) ;
}
media: add tuner standby op, use where needed
The v4l2_subdev core s_power op was used for two different things: power on/off
sensors or video decoders/encoders and to put a tuner in standby (and only the
tuner!). There is no 'tuner wakeup' op, that's done automatically when the tuner
is accessed.
The danger with calling (s_power, 0) to put a tuner into standby is that it is
usually broadcast for all subdevs. So a video receiver subdev that supports
s_power will also be powered off, and since there is no corresponding (s_power, 1)
they will never be powered on again.
In addition, this is specifically meant for tuners only since they draw the most
current.
This patch adds a new tuner op called 'standby' and replaces all calls to
(core, s_power, 0) by (tuner, standby). This prevents confusion between the two
uses of s_power. Note that there is no overlap: bridge drivers either just want
to put the tuner into standby, or they deal with powering on/off sensors. Never
both.
This also makes it easier to replace s_power for the remaining bridge drivers
with some PM code later.
Whether we want something cleaner for tuners in the future is a separate topic.
There is a lot of legacy code surrounding tuners, and I am very hesitant about
making changes there.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2018-02-21 02:49:25 -05:00
static int e4000_standby ( struct v4l2_subdev * sd )
2015-05-12 14:26:07 -03:00
{
struct e4000_dev * dev = e4000_subdev_to_dev ( sd ) ;
int ret ;
2012-09-01 21:09:21 -03:00
media: add tuner standby op, use where needed
The v4l2_subdev core s_power op was used for two different things: power on/off
sensors or video decoders/encoders and to put a tuner in standby (and only the
tuner!). There is no 'tuner wakeup' op, that's done automatically when the tuner
is accessed.
The danger with calling (s_power, 0) to put a tuner into standby is that it is
usually broadcast for all subdevs. So a video receiver subdev that supports
s_power will also be powered off, and since there is no corresponding (s_power, 1)
they will never be powered on again.
In addition, this is specifically meant for tuners only since they draw the most
current.
This patch adds a new tuner op called 'standby' and replaces all calls to
(core, s_power, 0) by (tuner, standby). This prevents confusion between the two
uses of s_power. Note that there is no overlap: bridge drivers either just want
to put the tuner into standby, or they deal with powering on/off sensors. Never
both.
This also makes it easier to replace s_power for the remaining bridge drivers
with some PM code later.
Whether we want something cleaner for tuners in the future is a separate topic.
There is a lot of legacy code surrounding tuners, and I am very hesitant about
making changes there.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2018-02-21 02:49:25 -05:00
ret = e4000_sleep ( dev ) ;
2015-05-12 14:26:07 -03:00
if ( ret )
return ret ;
return e4000_set_params ( dev ) ;
}
static int e4000_g_tuner ( struct v4l2_subdev * sd , struct v4l2_tuner * v )
{
struct e4000_dev * dev = e4000_subdev_to_dev ( sd ) ;
struct i2c_client * client = dev - > client ;
dev_dbg ( & client - > dev , " index=%d \n " , v - > index ) ;
2018-09-10 08:19:14 -04:00
strscpy ( v - > name , " Elonics E4000 " , sizeof ( v - > name ) ) ;
2015-05-12 14:26:07 -03:00
v - > type = V4L2_TUNER_RF ;
v - > capability = V4L2_TUNER_CAP_1HZ | V4L2_TUNER_CAP_FREQ_BANDS ;
v - > rangelow = bands [ 0 ] . rangelow ;
v - > rangehigh = bands [ 1 ] . rangehigh ;
2012-09-01 21:09:21 -03:00
return 0 ;
}
2015-05-12 14:26:07 -03:00
static int e4000_s_tuner ( struct v4l2_subdev * sd , const struct v4l2_tuner * v )
{
struct e4000_dev * dev = e4000_subdev_to_dev ( sd ) ;
struct i2c_client * client = dev - > client ;
dev_dbg ( & client - > dev , " index=%d \n " , v - > index ) ;
return 0 ;
}
static int e4000_g_frequency ( struct v4l2_subdev * sd , struct v4l2_frequency * f )
{
struct e4000_dev * dev = e4000_subdev_to_dev ( sd ) ;
struct i2c_client * client = dev - > client ;
dev_dbg ( & client - > dev , " tuner=%d \n " , f - > tuner ) ;
f - > frequency = dev - > f_frequency ;
return 0 ;
}
static int e4000_s_frequency ( struct v4l2_subdev * sd ,
const struct v4l2_frequency * f )
{
struct e4000_dev * dev = e4000_subdev_to_dev ( sd ) ;
struct i2c_client * client = dev - > client ;
dev_dbg ( & client - > dev , " tuner=%d type=%d frequency=%u \n " ,
f - > tuner , f - > type , f - > frequency ) ;
dev - > f_frequency = clamp_t ( unsigned int , f - > frequency ,
bands [ 0 ] . rangelow , bands [ 1 ] . rangehigh ) ;
return e4000_set_params ( dev ) ;
}
static int e4000_enum_freq_bands ( struct v4l2_subdev * sd ,
struct v4l2_frequency_band * band )
{
struct e4000_dev * dev = e4000_subdev_to_dev ( sd ) ;
struct i2c_client * client = dev - > client ;
dev_dbg ( & client - > dev , " tuner=%d type=%d index=%d \n " ,
band - > tuner , band - > type , band - > index ) ;
if ( band - > index > = ARRAY_SIZE ( bands ) )
return - EINVAL ;
band - > capability = bands [ band - > index ] . capability ;
band - > rangelow = bands [ band - > index ] . rangelow ;
band - > rangehigh = bands [ band - > index ] . rangehigh ;
return 0 ;
}
static const struct v4l2_subdev_tuner_ops e4000_subdev_tuner_ops = {
media: add tuner standby op, use where needed
The v4l2_subdev core s_power op was used for two different things: power on/off
sensors or video decoders/encoders and to put a tuner in standby (and only the
tuner!). There is no 'tuner wakeup' op, that's done automatically when the tuner
is accessed.
The danger with calling (s_power, 0) to put a tuner into standby is that it is
usually broadcast for all subdevs. So a video receiver subdev that supports
s_power will also be powered off, and since there is no corresponding (s_power, 1)
they will never be powered on again.
In addition, this is specifically meant for tuners only since they draw the most
current.
This patch adds a new tuner op called 'standby' and replaces all calls to
(core, s_power, 0) by (tuner, standby). This prevents confusion between the two
uses of s_power. Note that there is no overlap: bridge drivers either just want
to put the tuner into standby, or they deal with powering on/off sensors. Never
both.
This also makes it easier to replace s_power for the remaining bridge drivers
with some PM code later.
Whether we want something cleaner for tuners in the future is a separate topic.
There is a lot of legacy code surrounding tuners, and I am very hesitant about
making changes there.
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
2018-02-21 02:49:25 -05:00
. standby = e4000_standby ,
2015-05-12 14:26:07 -03:00
. g_tuner = e4000_g_tuner ,
. s_tuner = e4000_s_tuner ,
. g_frequency = e4000_g_frequency ,
. s_frequency = e4000_s_frequency ,
. enum_freq_bands = e4000_enum_freq_bands ,
} ;
static const struct v4l2_subdev_ops e4000_subdev_ops = {
. tuner = & e4000_subdev_tuner_ops ,
} ;
2014-01-26 21:02:53 -03:00
static int e4000_set_lna_gain ( struct dvb_frontend * fe )
{
2015-04-21 17:13:39 -03:00
struct e4000_dev * dev = fe - > tuner_priv ;
struct i2c_client * client = dev - > client ;
2014-01-26 21:02:53 -03:00
int ret ;
u8 u8tmp ;
2014-02-08 04:21:10 -03:00
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev , " lna auto=%d->%d val=%d->%d \n " ,
dev - > lna_gain_auto - > cur . val , dev - > lna_gain_auto - > val ,
dev - > lna_gain - > cur . val , dev - > lna_gain - > val ) ;
2014-01-26 21:02:53 -03:00
2015-04-21 17:13:39 -03:00
if ( dev - > lna_gain_auto - > val & & dev - > if_gain_auto - > cur . val )
2014-01-26 21:02:53 -03:00
u8tmp = 0x17 ;
2015-04-21 17:13:39 -03:00
else if ( dev - > lna_gain_auto - > val )
2014-01-26 21:02:53 -03:00
u8tmp = 0x19 ;
2015-04-21 17:13:39 -03:00
else if ( dev - > if_gain_auto - > cur . val )
2014-01-26 21:02:53 -03:00
u8tmp = 0x16 ;
else
u8tmp = 0x10 ;
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x1a , u8tmp ) ;
2014-01-26 21:02:53 -03:00
if ( ret )
goto err ;
2015-04-21 17:13:39 -03:00
if ( dev - > lna_gain_auto - > val = = false ) {
ret = regmap_write ( dev - > regmap , 0x14 , dev - > lna_gain - > val ) ;
2014-01-26 21:02:53 -03:00
if ( ret )
goto err ;
}
2015-04-21 17:13:39 -03:00
return 0 ;
err :
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2014-01-26 21:02:53 -03:00
return ret ;
}
static int e4000_set_mixer_gain ( struct dvb_frontend * fe )
{
2015-04-21 17:13:39 -03:00
struct e4000_dev * dev = fe - > tuner_priv ;
struct i2c_client * client = dev - > client ;
2014-01-26 21:02:53 -03:00
int ret ;
u8 u8tmp ;
2014-02-08 04:21:10 -03:00
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev , " mixer auto=%d->%d val=%d->%d \n " ,
dev - > mixer_gain_auto - > cur . val , dev - > mixer_gain_auto - > val ,
dev - > mixer_gain - > cur . val , dev - > mixer_gain - > val ) ;
2014-01-26 21:02:53 -03:00
2015-04-21 17:13:39 -03:00
if ( dev - > mixer_gain_auto - > val )
2014-01-26 21:02:53 -03:00
u8tmp = 0x15 ;
else
u8tmp = 0x14 ;
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x20 , u8tmp ) ;
2014-01-26 21:02:53 -03:00
if ( ret )
goto err ;
2015-04-21 17:13:39 -03:00
if ( dev - > mixer_gain_auto - > val = = false ) {
ret = regmap_write ( dev - > regmap , 0x15 , dev - > mixer_gain - > val ) ;
2014-01-26 21:02:53 -03:00
if ( ret )
goto err ;
}
2015-04-21 17:13:39 -03:00
return 0 ;
err :
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2014-01-26 21:02:53 -03:00
return ret ;
}
static int e4000_set_if_gain ( struct dvb_frontend * fe )
{
2015-04-21 17:13:39 -03:00
struct e4000_dev * dev = fe - > tuner_priv ;
struct i2c_client * client = dev - > client ;
2014-01-26 21:02:53 -03:00
int ret ;
u8 buf [ 2 ] ;
u8 u8tmp ;
2014-02-08 04:21:10 -03:00
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev , " if auto=%d->%d val=%d->%d \n " ,
dev - > if_gain_auto - > cur . val , dev - > if_gain_auto - > val ,
dev - > if_gain - > cur . val , dev - > if_gain - > val ) ;
2014-01-26 21:02:53 -03:00
2015-04-21 17:13:39 -03:00
if ( dev - > if_gain_auto - > val & & dev - > lna_gain_auto - > cur . val )
2014-01-26 21:02:53 -03:00
u8tmp = 0x17 ;
2015-04-21 17:13:39 -03:00
else if ( dev - > lna_gain_auto - > cur . val )
2014-01-26 21:02:53 -03:00
u8tmp = 0x19 ;
2015-04-21 17:13:39 -03:00
else if ( dev - > if_gain_auto - > val )
2014-01-26 21:02:53 -03:00
u8tmp = 0x16 ;
else
u8tmp = 0x10 ;
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x1a , u8tmp ) ;
2014-01-26 21:02:53 -03:00
if ( ret )
goto err ;
2015-04-21 17:13:39 -03:00
if ( dev - > if_gain_auto - > val = = false ) {
buf [ 0 ] = e4000_if_gain_lut [ dev - > if_gain - > val ] . reg16_val ;
buf [ 1 ] = e4000_if_gain_lut [ dev - > if_gain - > val ] . reg17_val ;
ret = regmap_bulk_write ( dev - > regmap , 0x16 , buf , 2 ) ;
2014-01-26 21:02:53 -03:00
if ( ret )
goto err ;
}
2015-04-21 17:13:39 -03:00
return 0 ;
err :
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2014-01-26 21:02:53 -03:00
return ret ;
}
2014-02-07 02:55:57 -03:00
static int e4000_pll_lock ( struct dvb_frontend * fe )
{
2015-04-21 17:13:39 -03:00
struct e4000_dev * dev = fe - > tuner_priv ;
struct i2c_client * client = dev - > client ;
2014-02-07 02:55:57 -03:00
int ret ;
2015-04-21 17:13:39 -03:00
unsigned int uitmp ;
2014-02-07 02:55:57 -03:00
2015-04-21 17:13:39 -03:00
ret = regmap_read ( dev - > regmap , 0x07 , & uitmp ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2014-02-07 02:55:57 -03:00
goto err ;
2015-04-21 17:13:39 -03:00
dev - > pll_lock - > val = ( uitmp & 0x01 ) ;
2014-02-07 02:55:57 -03:00
2015-04-21 17:13:39 -03:00
return 0 ;
err :
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2014-02-07 02:55:57 -03:00
return ret ;
}
static int e4000_g_volatile_ctrl ( struct v4l2_ctrl * ctrl )
{
2015-04-21 17:13:39 -03:00
struct e4000_dev * dev = container_of ( ctrl - > handler , struct e4000_dev , hdl ) ;
struct i2c_client * client = dev - > client ;
2014-02-07 02:55:57 -03:00
int ret ;
2015-04-21 17:13:39 -03:00
if ( ! dev - > active )
2014-02-08 06:20:35 -03:00
return 0 ;
2014-02-07 02:55:57 -03:00
switch ( ctrl - > id ) {
case V4L2_CID_RF_TUNER_PLL_LOCK :
2015-04-21 17:13:39 -03:00
ret = e4000_pll_lock ( dev - > fe ) ;
2014-02-07 02:55:57 -03:00
break ;
default :
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev , " unknown ctrl: id=%d name=%s \n " ,
ctrl - > id , ctrl - > name ) ;
2014-02-07 02:55:57 -03:00
ret = - EINVAL ;
}
return ret ;
}
2014-01-26 21:02:53 -03:00
static int e4000_s_ctrl ( struct v4l2_ctrl * ctrl )
{
2015-04-21 17:13:39 -03:00
struct e4000_dev * dev = container_of ( ctrl - > handler , struct e4000_dev , hdl ) ;
struct i2c_client * client = dev - > client ;
2014-01-26 21:02:53 -03:00
int ret ;
2014-02-08 04:21:10 -03:00
2015-04-21 17:13:39 -03:00
if ( ! dev - > active )
2014-02-08 06:20:35 -03:00
return 0 ;
2014-01-26 21:02:53 -03:00
switch ( ctrl - > id ) {
case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO :
case V4L2_CID_RF_TUNER_BANDWIDTH :
2015-05-12 14:26:07 -03:00
/*
* TODO : Auto logic does not work 100 % correctly as tuner driver
* do not have information to calculate maximum suitable
* bandwidth . Calculating it is responsible of master driver .
*/
dev - > f_bandwidth = dev - > bandwidth - > val ;
ret = e4000_set_params ( dev ) ;
2014-01-26 21:02:53 -03:00
break ;
case V4L2_CID_RF_TUNER_LNA_GAIN_AUTO :
case V4L2_CID_RF_TUNER_LNA_GAIN :
2015-04-21 17:13:39 -03:00
ret = e4000_set_lna_gain ( dev - > fe ) ;
2014-01-26 21:02:53 -03:00
break ;
case V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO :
case V4L2_CID_RF_TUNER_MIXER_GAIN :
2015-04-21 17:13:39 -03:00
ret = e4000_set_mixer_gain ( dev - > fe ) ;
2014-01-26 21:02:53 -03:00
break ;
case V4L2_CID_RF_TUNER_IF_GAIN_AUTO :
case V4L2_CID_RF_TUNER_IF_GAIN :
2015-04-21 17:13:39 -03:00
ret = e4000_set_if_gain ( dev - > fe ) ;
2014-01-26 21:02:53 -03:00
break ;
default :
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev , " unknown ctrl: id=%d name=%s \n " ,
ctrl - > id , ctrl - > name ) ;
2014-01-26 21:02:53 -03:00
ret = - EINVAL ;
}
return ret ;
}
static const struct v4l2_ctrl_ops e4000_ctrl_ops = {
2014-02-07 02:55:57 -03:00
. g_volatile_ctrl = e4000_g_volatile_ctrl ,
2014-01-26 21:02:53 -03:00
. s_ctrl = e4000_s_ctrl ,
} ;
2014-03-16 18:13:05 -03:00
# endif
2014-01-26 21:02:53 -03:00
2015-05-12 14:26:07 -03:00
/*
* DVB API
*/
static int e4000_dvb_set_params ( struct dvb_frontend * fe )
{
struct e4000_dev * dev = fe - > tuner_priv ;
struct dtv_frontend_properties * c = & fe - > dtv_property_cache ;
dev - > f_frequency = c - > frequency ;
dev - > f_bandwidth = c - > bandwidth_hz ;
return e4000_set_params ( dev ) ;
}
static int e4000_dvb_init ( struct dvb_frontend * fe )
{
return e4000_init ( fe - > tuner_priv ) ;
}
static int e4000_dvb_sleep ( struct dvb_frontend * fe )
{
return e4000_sleep ( fe - > tuner_priv ) ;
}
static int e4000_dvb_get_if_frequency ( struct dvb_frontend * fe , u32 * frequency )
{
* frequency = 0 ; /* Zero-IF */
return 0 ;
}
static const struct dvb_tuner_ops e4000_dvb_tuner_ops = {
2012-09-01 21:09:21 -03:00
. info = {
2018-07-05 18:59:35 -04:00
. name = " Elonics E4000 " ,
. frequency_min_hz = 174 * MHz ,
. frequency_max_hz = 862 * MHz ,
2012-09-01 21:09:21 -03:00
} ,
2015-05-12 14:26:07 -03:00
. init = e4000_dvb_init ,
. sleep = e4000_dvb_sleep ,
. set_params = e4000_dvb_set_params ,
2012-09-01 21:09:21 -03:00
2015-05-12 14:26:07 -03:00
. get_if_frequency = e4000_dvb_get_if_frequency ,
2012-09-01 21:09:21 -03:00
} ;
2022-11-18 23:42:14 +01:00
static int e4000_probe ( struct i2c_client * client )
2012-09-01 21:09:21 -03:00
{
2015-04-21 17:13:39 -03:00
struct e4000_dev * dev ;
2013-10-15 19:22:45 -03:00
struct e4000_config * cfg = client - > dev . platform_data ;
struct dvb_frontend * fe = cfg - > fe ;
2012-09-01 21:09:21 -03:00
int ret ;
2015-04-21 17:13:39 -03:00
unsigned int uitmp ;
2014-02-08 06:20:35 -03:00
static const struct regmap_config regmap_config = {
. reg_bits = 8 ,
. val_bits = 8 ,
} ;
2012-09-01 21:09:21 -03:00
2015-04-21 17:13:39 -03:00
dev = kzalloc ( sizeof ( * dev ) , GFP_KERNEL ) ;
if ( ! dev ) {
2012-09-01 21:09:21 -03:00
ret = - ENOMEM ;
goto err ;
}
2015-04-21 17:13:39 -03:00
dev - > clk = cfg - > clock ;
dev - > client = client ;
dev - > fe = cfg - > fe ;
dev - > regmap = devm_regmap_init_i2c ( client , & regmap_config ) ;
if ( IS_ERR ( dev - > regmap ) ) {
ret = PTR_ERR ( dev - > regmap ) ;
goto err_kfree ;
2014-02-08 06:20:35 -03:00
}
2012-09-01 21:09:21 -03:00
/* check if the tuner is there */
2015-04-21 17:13:39 -03:00
ret = regmap_read ( dev - > regmap , 0x02 , & uitmp ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2015-04-21 17:13:39 -03:00
goto err_kfree ;
2012-09-01 21:09:21 -03:00
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev , " chip id=%02x \n " , uitmp ) ;
2012-09-01 21:09:21 -03:00
2015-04-21 17:13:39 -03:00
if ( uitmp ! = 0x40 ) {
2013-10-15 19:22:45 -03:00
ret = - ENODEV ;
2015-04-21 17:13:39 -03:00
goto err_kfree ;
2013-10-15 19:22:45 -03:00
}
2012-09-01 21:09:21 -03:00
/* put sleep as chip seems to be in normal mode by default */
2015-04-21 17:13:39 -03:00
ret = regmap_write ( dev - > regmap , 0x00 , 0x00 ) ;
2014-02-10 22:52:51 -03:00
if ( ret )
2015-04-21 17:13:39 -03:00
goto err_kfree ;
2012-09-01 21:09:21 -03:00
media: Kconfig: cleanup VIDEO_DEV dependencies
media Kconfig has two entries associated to V4L API:
VIDEO_DEV and VIDEO_V4L2.
On Kernel 2.6.x, there were two V4L APIs, each one with its own flag.
VIDEO_DEV were meant to:
1) enable Video4Linux and make its Kconfig options to appear;
2) it makes the Kernel build the V4L core.
while VIDEO_V4L2 where used to distinguish between drivers that
implement the newer API and drivers that implemented the former one.
With time, such meaning changed, specially after the removal of
all V4L version 1 drivers.
At the current implementation, VIDEO_DEV only does (1): it enables
the media options related to V4L, that now has:
menu "Video4Linux options"
visible if VIDEO_DEV
source "drivers/media/v4l2-core/Kconfig"
endmenu
but it doesn't affect anymore the V4L core drivers.
The rationale is that the V4L2 core has a "soft" dependency
at the I2C bus, and now requires to select a number of other
Kconfig options:
config VIDEO_V4L2
tristate
depends on (I2C || I2C=n) && VIDEO_DEV
select RATIONAL
select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE
default (I2C || I2C=n) && VIDEO_DEV
In the past, merging them would be tricky, but it seems that it is now
possible to merge those symbols, in order to simplify V4L dependencies.
Let's keep VIDEO_DEV, as this one is used on some make *defconfig
configurations.
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> # for meson-vdec & meson-ge2d
Acked-by: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
Acked-by: Łukasz Stelmach <l.stelmach@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2022-03-13 07:25:46 +01:00
# if IS_ENABLED(CONFIG_VIDEO_DEV)
2014-01-26 21:02:53 -03:00
/* Register controls */
2015-04-21 17:13:39 -03:00
v4l2_ctrl_handler_init ( & dev - > hdl , 9 ) ;
dev - > bandwidth_auto = v4l2_ctrl_new_std ( & dev - > hdl , & e4000_ctrl_ops ,
2014-01-26 21:02:53 -03:00
V4L2_CID_RF_TUNER_BANDWIDTH_AUTO , 0 , 1 , 1 , 1 ) ;
2015-04-21 17:13:39 -03:00
dev - > bandwidth = v4l2_ctrl_new_std ( & dev - > hdl , & e4000_ctrl_ops ,
2014-01-26 21:02:53 -03:00
V4L2_CID_RF_TUNER_BANDWIDTH , 4300000 , 11000000 , 100000 , 4300000 ) ;
2015-04-21 17:13:39 -03:00
v4l2_ctrl_auto_cluster ( 2 , & dev - > bandwidth_auto , 0 , false ) ;
dev - > lna_gain_auto = v4l2_ctrl_new_std ( & dev - > hdl , & e4000_ctrl_ops ,
2014-01-26 21:02:53 -03:00
V4L2_CID_RF_TUNER_LNA_GAIN_AUTO , 0 , 1 , 1 , 1 ) ;
2015-04-21 17:13:39 -03:00
dev - > lna_gain = v4l2_ctrl_new_std ( & dev - > hdl , & e4000_ctrl_ops ,
2014-01-26 21:02:53 -03:00
V4L2_CID_RF_TUNER_LNA_GAIN , 0 , 15 , 1 , 10 ) ;
2015-04-21 17:13:39 -03:00
v4l2_ctrl_auto_cluster ( 2 , & dev - > lna_gain_auto , 0 , false ) ;
dev - > mixer_gain_auto = v4l2_ctrl_new_std ( & dev - > hdl , & e4000_ctrl_ops ,
2014-01-26 21:02:53 -03:00
V4L2_CID_RF_TUNER_MIXER_GAIN_AUTO , 0 , 1 , 1 , 1 ) ;
2015-04-21 17:13:39 -03:00
dev - > mixer_gain = v4l2_ctrl_new_std ( & dev - > hdl , & e4000_ctrl_ops ,
2014-01-26 21:02:53 -03:00
V4L2_CID_RF_TUNER_MIXER_GAIN , 0 , 1 , 1 , 1 ) ;
2015-04-21 17:13:39 -03:00
v4l2_ctrl_auto_cluster ( 2 , & dev - > mixer_gain_auto , 0 , false ) ;
dev - > if_gain_auto = v4l2_ctrl_new_std ( & dev - > hdl , & e4000_ctrl_ops ,
2014-01-26 21:02:53 -03:00
V4L2_CID_RF_TUNER_IF_GAIN_AUTO , 0 , 1 , 1 , 1 ) ;
2015-04-21 17:13:39 -03:00
dev - > if_gain = v4l2_ctrl_new_std ( & dev - > hdl , & e4000_ctrl_ops ,
2014-01-26 21:02:53 -03:00
V4L2_CID_RF_TUNER_IF_GAIN , 0 , 54 , 1 , 0 ) ;
2015-04-21 17:13:39 -03:00
v4l2_ctrl_auto_cluster ( 2 , & dev - > if_gain_auto , 0 , false ) ;
dev - > pll_lock = v4l2_ctrl_new_std ( & dev - > hdl , & e4000_ctrl_ops ,
2014-02-07 02:55:57 -03:00
V4L2_CID_RF_TUNER_PLL_LOCK , 0 , 1 , 1 , 0 ) ;
2015-04-21 17:13:39 -03:00
if ( dev - > hdl . error ) {
ret = dev - > hdl . error ;
dev_err ( & client - > dev , " Could not initialize controls \n " ) ;
v4l2_ctrl_handler_free ( & dev - > hdl ) ;
goto err_kfree ;
2014-01-26 21:02:53 -03:00
}
2015-04-21 17:13:39 -03:00
dev - > sd . ctrl_handler = & dev - > hdl ;
2015-05-12 14:26:07 -03:00
dev - > f_frequency = bands [ 0 ] . rangelow ;
dev - > f_bandwidth = dev - > bandwidth - > val ;
v4l2_i2c_subdev_init ( & dev - > sd , client , & e4000_subdev_ops ) ;
2014-03-16 18:13:05 -03:00
# endif
2015-04-21 17:13:39 -03:00
fe - > tuner_priv = dev ;
2015-05-12 14:26:07 -03:00
memcpy ( & fe - > ops . tuner_ops , & e4000_dvb_tuner_ops ,
sizeof ( fe - > ops . tuner_ops ) ) ;
2015-04-21 17:13:39 -03:00
v4l2_set_subdevdata ( & dev - > sd , client ) ;
i2c_set_clientdata ( client , & dev - > sd ) ;
2012-09-22 12:32:27 -03:00
2015-04-21 17:13:39 -03:00
dev_info ( & client - > dev , " Elonics E4000 successfully identified \n " ) ;
2013-10-15 19:22:45 -03:00
return 0 ;
2015-04-21 17:13:39 -03:00
err_kfree :
kfree ( dev ) ;
2012-09-01 21:09:21 -03:00
err :
2015-04-21 17:13:39 -03:00
dev_dbg ( & client - > dev , " failed=%d \n " , ret ) ;
2013-10-15 19:22:45 -03:00
return ret ;
2012-09-01 21:09:21 -03:00
}
2013-10-15 19:22:45 -03:00
2022-08-15 10:02:30 +02:00
static void e4000_remove ( struct i2c_client * client )
2013-10-15 19:22:45 -03:00
{
2014-01-26 21:02:53 -03:00
struct v4l2_subdev * sd = i2c_get_clientdata ( client ) ;
2015-04-21 17:13:39 -03:00
struct e4000_dev * dev = container_of ( sd , struct e4000_dev , sd ) ;
2013-10-15 19:22:45 -03:00
2014-08-24 23:35:48 -03:00
dev_dbg ( & client - > dev , " \n " ) ;
2014-02-08 04:21:10 -03:00
media: Kconfig: cleanup VIDEO_DEV dependencies
media Kconfig has two entries associated to V4L API:
VIDEO_DEV and VIDEO_V4L2.
On Kernel 2.6.x, there were two V4L APIs, each one with its own flag.
VIDEO_DEV were meant to:
1) enable Video4Linux and make its Kconfig options to appear;
2) it makes the Kernel build the V4L core.
while VIDEO_V4L2 where used to distinguish between drivers that
implement the newer API and drivers that implemented the former one.
With time, such meaning changed, specially after the removal of
all V4L version 1 drivers.
At the current implementation, VIDEO_DEV only does (1): it enables
the media options related to V4L, that now has:
menu "Video4Linux options"
visible if VIDEO_DEV
source "drivers/media/v4l2-core/Kconfig"
endmenu
but it doesn't affect anymore the V4L core drivers.
The rationale is that the V4L2 core has a "soft" dependency
at the I2C bus, and now requires to select a number of other
Kconfig options:
config VIDEO_V4L2
tristate
depends on (I2C || I2C=n) && VIDEO_DEV
select RATIONAL
select VIDEOBUF2_V4L2 if VIDEOBUF2_CORE
default (I2C || I2C=n) && VIDEO_DEV
In the past, merging them would be tricky, but it seems that it is now
possible to merge those symbols, in order to simplify V4L dependencies.
Let's keep VIDEO_DEV, as this one is used on some make *defconfig
configurations.
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Neil Armstrong <narmstrong@baylibre.com> # for meson-vdec & meson-ge2d
Acked-by: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
Acked-by: Łukasz Stelmach <l.stelmach@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
2022-03-13 07:25:46 +01:00
# if IS_ENABLED(CONFIG_VIDEO_DEV)
2015-04-21 17:13:39 -03:00
v4l2_ctrl_handler_free ( & dev - > hdl ) ;
2014-03-16 18:13:05 -03:00
# endif
2015-04-21 17:13:39 -03:00
kfree ( dev ) ;
2013-10-15 19:22:45 -03:00
}
2015-04-21 17:13:39 -03:00
static const struct i2c_device_id e4000_id_table [ ] = {
2013-10-15 19:22:45 -03:00
{ " e4000 " , 0 } ,
{ }
} ;
2015-04-21 17:13:39 -03:00
MODULE_DEVICE_TABLE ( i2c , e4000_id_table ) ;
2013-10-15 19:22:45 -03:00
static struct i2c_driver e4000_driver = {
. driver = {
. name = " e4000 " ,
2015-04-21 17:13:39 -03:00
. suppress_bind_attrs = true ,
2013-10-15 19:22:45 -03:00
} ,
2023-05-14 14:04:07 +02:00
. probe = e4000_probe ,
2013-10-15 19:22:45 -03:00
. remove = e4000_remove ,
2015-04-21 17:13:39 -03:00
. id_table = e4000_id_table ,
2013-10-15 19:22:45 -03:00
} ;
module_i2c_driver ( e4000_driver ) ;
2012-09-01 21:09:21 -03:00
MODULE_DESCRIPTION ( " Elonics E4000 silicon tuner driver " ) ;
MODULE_AUTHOR ( " Antti Palosaari <crope@iki.fi> " ) ;
MODULE_LICENSE ( " GPL " ) ;