diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/usb/cx231xx/cx231xx-dvb.c | 330 |
1 files changed, 78 insertions, 252 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-dvb.c b/drivers/media/usb/cx231xx/cx231xx-dvb.c index 86c33f5ff1a3..53831007c92d 100644 --- a/drivers/media/usb/cx231xx/cx231xx-dvb.c +++ b/drivers/media/usb/cx231xx/cx231xx-dvb.c @@ -617,23 +617,15 @@ static void unregister_dvb(struct cx231xx_dvb *dvb) dvb_frontend_detach(dvb->frontend[1]); dvb_frontend_detach(dvb->frontend[0]); dvb_unregister_adapter(&dvb->adapter); + /* remove I2C tuner */ - client = dvb->i2c_client_tuner; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - } - /* remove I2C demod */ - client = dvb->i2c_client_demod[1]; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - } - client = dvb->i2c_client_demod[0]; - if (client) { - module_put(client->dev.driver->owner); - i2c_unregister_device(client); - } + dvb_module_release(dvb->i2c_client_tuner); + dvb->i2c_client_tuner = NULL; + /* remove I2C demod(s) */ + dvb_module_release(dvb->i2c_client_demod[1]); + dvb->i2c_client_demod[1] = NULL; + dvb_module_release(dvb->i2c_client_demod[0]); + dvb->i2c_client_demod[0] = NULL; } static int dvb_init(struct cx231xx *dev) @@ -642,6 +634,8 @@ static int dvb_init(struct cx231xx *dev) struct cx231xx_dvb *dvb; struct i2c_adapter *tuner_i2c; struct i2c_adapter *demod_i2c; + struct i2c_client *client; + struct i2c_adapter *adapter; if (!dev->board.has_dvb) { /* This device does not support the extension */ @@ -789,8 +783,6 @@ static int dvb_init(struct cx231xx *dev) case CX231XX_BOARD_HAUPPAUGE_930C_HD_1113xx: { - struct i2c_client *client; - struct i2c_board_info info; struct si2165_platform_data si2165_pdata = {}; /* attach demod */ @@ -798,25 +790,14 @@ static int dvb_init(struct cx231xx *dev) si2165_pdata.chip_mode = SI2165_MODE_PLL_XTAL; si2165_pdata.ref_freq_hz = 16000000; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2165", I2C_NAME_SIZE); - info.addr = dev->board.demod_addr; - info.platform_data = &si2165_pdata; - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); - if (!client || !client->dev.driver || !dev->dvb->frontend[0]) { - dev_err(dev->dev, - "Failed to attach SI2165 front end\n"); - result = -EINVAL; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); + /* perform probe/init/attach */ + client = dvb_module_probe("si2165", NULL, demod_i2c, + dev->board.demod_addr, + &si2165_pdata); + if (!client) { result = -ENODEV; goto out_free; } - dvb->i2c_client_demod[0] = client; dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; @@ -833,8 +814,6 @@ static int dvb_init(struct cx231xx *dev) } case CX231XX_BOARD_HAUPPAUGE_930C_HD_1114xx: { - struct i2c_client *client; - struct i2c_board_info info; struct si2165_platform_data si2165_pdata = {}; struct si2157_config si2157_config = {}; @@ -843,29 +822,16 @@ static int dvb_init(struct cx231xx *dev) si2165_pdata.chip_mode = SI2165_MODE_PLL_EXT; si2165_pdata.ref_freq_hz = 24000000; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2165", I2C_NAME_SIZE); - info.addr = dev->board.demod_addr; - info.platform_data = &si2165_pdata; - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); - if (!client || !client->dev.driver || !dev->dvb->frontend[0]) { - dev_err(dev->dev, - "Failed to attach SI2165 front end\n"); - result = -EINVAL; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); + /* perform probe/init/attach */ + client = dvb_module_probe("si2165", NULL, demod_i2c, + dev->board.demod_addr, + &si2165_pdata); + if (!client) { result = -ENODEV; goto out_free; } - dvb->i2c_client_demod[0] = client; - memset(&info, 0, sizeof(struct i2c_board_info)); - dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; /* define general-purpose callback pointer */ @@ -878,27 +844,15 @@ static int dvb_init(struct cx231xx *dev) #endif si2157_config.if_port = 1; si2157_config.inversion = true; - strlcpy(info.type, "si2157", I2C_NAME_SIZE); - info.addr = dev->board.tuner_addr; - info.platform_data = &si2157_config; - request_module("si2157"); - - client = i2c_new_device( - tuner_i2c, - &info); - if (client == NULL || client->dev.driver == NULL) { - dvb_frontend_detach(dev->dvb->frontend[0]); - result = -ENODEV; - goto out_free; - } - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - dvb_frontend_detach(dev->dvb->frontend[0]); + /* perform probe/init/attach */ + client = dvb_module_probe("si2157", NULL, tuner_i2c, + dev->board.tuner_addr, + &si2157_config); + if (!client) { result = -ENODEV; goto out_free; } - dev->cx231xx_reset_analog_tuner = NULL; dev->dvb->i2c_client_tuner = client; @@ -906,12 +860,8 @@ static int dvb_init(struct cx231xx *dev) } case CX231XX_BOARD_HAUPPAUGE_955Q: { - struct i2c_client *client; - struct i2c_board_info info; struct si2157_config si2157_config = {}; - memset(&info, 0, sizeof(struct i2c_board_info)); - dev->dvb->frontend[0] = dvb_attach(lgdt3306a_attach, &hauppauge_955q_lgdt3306a_config, demod_i2c @@ -936,27 +886,15 @@ static int dvb_init(struct cx231xx *dev) #endif si2157_config.if_port = 1; si2157_config.inversion = true; - strlcpy(info.type, "si2157", I2C_NAME_SIZE); - info.addr = dev->board.tuner_addr; - info.platform_data = &si2157_config; - request_module("si2157"); - - client = i2c_new_device( - tuner_i2c, - &info); - if (client == NULL || client->dev.driver == NULL) { - dvb_frontend_detach(dev->dvb->frontend[0]); - result = -ENODEV; - goto out_free; - } - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - dvb_frontend_detach(dev->dvb->frontend[0]); + /* perform probe/init/attach */ + client = dvb_module_probe("si2157", NULL, tuner_i2c, + dev->board.tuner_addr, + &si2157_config); + if (!client) { result = -ENODEV; goto out_free; } - dev->cx231xx_reset_analog_tuner = NULL; dev->dvb->i2c_client_tuner = client; @@ -992,9 +930,6 @@ static int dvb_init(struct cx231xx *dev) { struct si2157_config si2157_config = {}; struct si2168_config si2168_config = {}; - struct i2c_board_info info = {}; - struct i2c_client *client; - struct i2c_adapter *adapter; /* attach demodulator chip */ si2168_config.ts_mode = SI2168_TS_SERIAL; /* from *.inf file */ @@ -1002,24 +937,14 @@ static int dvb_init(struct cx231xx *dev) si2168_config.i2c_adapter = &adapter; si2168_config.ts_clock_inv = true; - strlcpy(info.type, "si2168", sizeof(info.type)); - info.addr = dev->board.demod_addr; - info.platform_data = &si2168_config; - - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); - - if (client == NULL || client->dev.driver == NULL) { + /* perform probe/init/attach */ + client = dvb_module_probe("si2168", NULL, demod_i2c, + dev->board.demod_addr, + &si2168_config); + if (!client) { result = -ENODEV; goto out_free; } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - dvb->i2c_client_demod[0] = client; /* attach tuner chip */ @@ -1030,37 +955,20 @@ static int dvb_init(struct cx231xx *dev) si2157_config.if_port = 1; si2157_config.inversion = false; - memset(&info, 0, sizeof(info)); - strlcpy(info.type, "si2157", sizeof(info.type)); - info.addr = dev->board.tuner_addr; - info.platform_data = &si2157_config; - - request_module(info.type); - client = i2c_new_device(tuner_i2c, &info); - - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod[0]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[0]); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod[0]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[0]); + /* perform probe/init/attach */ + client = dvb_module_probe("si2157", NULL, tuner_i2c, + dev->board.tuner_addr, + &si2157_config); + if (!client) { result = -ENODEV; goto out_free; } - dev->cx231xx_reset_analog_tuner = NULL; dev->dvb->i2c_client_tuner = client; break; } case CX231XX_BOARD_ASTROMETA_T2HYBRID: { - struct i2c_client *client; - struct i2c_board_info info = {}; struct mn88473_config mn88473_config = {}; /* attach demodulator chip */ @@ -1068,24 +976,14 @@ static int dvb_init(struct cx231xx *dev) mn88473_config.xtal = 25000000; mn88473_config.fe = &dev->dvb->frontend[0]; - strlcpy(info.type, "mn88473", sizeof(info.type)); - info.addr = dev->board.demod_addr; - info.platform_data = &mn88473_config; - - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); - - if (client == NULL || client->dev.driver == NULL) { - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); + /* perform probe/init/attach */ + client = dvb_module_probe("mn88473", NULL, demod_i2c, + dev->board.demod_addr, + &mn88473_config); + if (!client) { result = -ENODEV; goto out_free; } - dvb->i2c_client_demod[0] = client; /* define general-purpose callback pointer */ @@ -1099,9 +997,6 @@ static int dvb_init(struct cx231xx *dev) } case CX231XX_BOARD_HAUPPAUGE_935C: { - struct i2c_client *client; - struct i2c_adapter *adapter; - struct i2c_board_info info = {}; struct si2157_config si2157_config = {}; struct si2168_config si2168_config = {}; @@ -1111,25 +1006,14 @@ static int dvb_init(struct cx231xx *dev) si2168_config.i2c_adapter = &adapter; si2168_config.ts_clock_inv = true; - strlcpy(info.type, "si2168", sizeof(info.type)); - info.addr = dev->board.demod_addr; - info.platform_data = &si2168_config; - - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); - if (client == NULL || client->dev.driver == NULL) { + /* perform probe/init/attach */ + client = dvb_module_probe("si2168", NULL, demod_i2c, + dev->board.demod_addr, + &si2168_config); + if (!client) { result = -ENODEV; goto out_free; } - - if (!try_module_get(client->dev.driver->owner)) { - dev_err(dev->dev, - "Failed to attach %s frontend.\n", info.type); - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - dvb->i2c_client_demod[0] = client; dev->dvb->frontend[0]->ops.i2c_gate_ctrl = NULL; @@ -1144,40 +1028,21 @@ static int dvb_init(struct cx231xx *dev) si2157_config.if_port = 1; si2157_config.inversion = true; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2157", I2C_NAME_SIZE); - info.addr = dev->board.tuner_addr; - info.platform_data = &si2157_config; - request_module("si2157"); - - client = i2c_new_device(tuner_i2c, &info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod[0]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[0]); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - dev_err(dev->dev, - "Failed to obtain %s tuner.\n", info.type); - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod[0]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[0]); + /* perform probe/init/attach */ + client = dvb_module_probe("si2157", NULL, tuner_i2c, + dev->board.tuner_addr, + &si2157_config); + if (!client) { result = -ENODEV; goto out_free; } - dev->cx231xx_reset_analog_tuner = NULL; dev->dvb->i2c_client_tuner = client; break; } case CX231XX_BOARD_HAUPPAUGE_975: { - struct i2c_client *client; - struct i2c_adapter *adapter; struct i2c_adapter *adapter2; - struct i2c_board_info info = {}; struct si2157_config si2157_config = {}; struct lgdt3306a_config lgdt3306a_config = {}; struct si2168_config si2168_config = {}; @@ -1188,25 +1053,14 @@ static int dvb_init(struct cx231xx *dev) lgdt3306a_config.i2c_adapter = &adapter; lgdt3306a_config.deny_i2c_rptr = 0; - strlcpy(info.type, "lgdt3306a", sizeof(info.type)); - info.addr = dev->board.demod_addr; - info.platform_data = &lgdt3306a_config; - - request_module(info.type); - client = i2c_new_device(demod_i2c, &info); - if (client == NULL || client->dev.driver == NULL) { + /* perform probe/init/attach */ + client = dvb_module_probe("lgdt3306a", NULL, demod_i2c, + dev->board.demod_addr, + &lgdt3306a_config); + if (!client) { result = -ENODEV; goto out_free; } - - if (!try_module_get(client->dev.driver->owner)) { - dev_err(dev->dev, - "Failed to attach %s frontend.\n", info.type); - i2c_unregister_device(client); - result = -ENODEV; - goto out_free; - } - dvb->i2c_client_demod[0] = client; /* attach second demodulator chip */ @@ -1215,30 +1069,14 @@ static int dvb_init(struct cx231xx *dev) si2168_config.i2c_adapter = &adapter2; si2168_config.ts_clock_inv = true; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2168", sizeof(info.type)); - info.addr = dev->board.demod_addr2; - info.platform_data = &si2168_config; - - request_module(info.type); - client = i2c_new_device(adapter, &info); - if (client == NULL || client->dev.driver == NULL) { - dev_err(dev->dev, - "Failed to attach %s frontend.\n", info.type); - module_put(dvb->i2c_client_demod[0]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[0]); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod[0]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[0]); + /* perform probe/init/attach */ + client = dvb_module_probe("si2168", NULL, adapter, + dev->board.demod_addr2, + &si2168_config); + if (!client) { result = -ENODEV; goto out_free; } - dvb->i2c_client_demod[1] = client; dvb->frontend[1]->id = 1; @@ -1254,34 +1092,14 @@ static int dvb_init(struct cx231xx *dev) si2157_config.if_port = 1; si2157_config.inversion = true; - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "si2157", I2C_NAME_SIZE); - info.addr = dev->board.tuner_addr; - info.platform_data = &si2157_config; - request_module("si2157"); - - client = i2c_new_device(adapter, &info); - if (client == NULL || client->dev.driver == NULL) { - module_put(dvb->i2c_client_demod[1]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[1]); - module_put(dvb->i2c_client_demod[0]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[0]); - result = -ENODEV; - goto out_free; - } - - if (!try_module_get(client->dev.driver->owner)) { - dev_err(dev->dev, - "Failed to obtain %s tuner.\n", info.type); - i2c_unregister_device(client); - module_put(dvb->i2c_client_demod[1]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[1]); - module_put(dvb->i2c_client_demod[0]->dev.driver->owner); - i2c_unregister_device(dvb->i2c_client_demod[0]); + /* perform probe/init/attach */ + client = dvb_module_probe("si2157", NULL, adapter, + dev->board.tuner_addr, + &si2157_config); + if (!client) { result = -ENODEV; goto out_free; } - dev->cx231xx_reset_analog_tuner = NULL; dvb->i2c_client_tuner = client; @@ -1320,6 +1138,14 @@ ret: return result; out_free: + /* remove I2C tuner */ + dvb_module_release(dvb->i2c_client_tuner); + dvb->i2c_client_tuner = NULL; + /* remove I2C demod(s) */ + dvb_module_release(dvb->i2c_client_demod[1]); + dvb->i2c_client_demod[1] = NULL; + dvb_module_release(dvb->i2c_client_demod[0]); + dvb->i2c_client_demod[0] = NULL; kfree(dvb); dev->dvb = NULL; goto ret; |