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

media: stv6110x: Implement probe/remove for stv6110x

Refactor out the common parts of stv6110x_probe() and stv6110x_attach()
into separate functions.

This provides the needed functionality to use dvb_module_probe() instead
of dvb_attach()!

Signed-off-by: Tobias Klausmann <tobias.johannes.klausmann@mni.thm.de>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>

authored by

Tobias Klausmann and committed by
Mauro Carvalho Chehab
3c8f4cd2 26594178

+118 -23
+113 -22
drivers/media/dvb-frontends/stv6110x.c
··· 333 333 kfree(stv6110x); 334 334 } 335 335 336 + static void st6110x_init_regs(struct stv6110x_state *stv6110x) 337 + { 338 + u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; 339 + 340 + memcpy(stv6110x->regs, default_regs, 8); 341 + } 342 + 343 + static void stv6110x_setup_divider(struct stv6110x_state *stv6110x) 344 + { 345 + switch (stv6110x->config->clk_div) { 346 + default: 347 + case 1: 348 + STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], 349 + CTRL2_CO_DIV, 350 + 0); 351 + break; 352 + case 2: 353 + STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], 354 + CTRL2_CO_DIV, 355 + 1); 356 + break; 357 + case 4: 358 + STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], 359 + CTRL2_CO_DIV, 360 + 2); 361 + break; 362 + case 8: 363 + case 0: 364 + STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], 365 + CTRL2_CO_DIV, 366 + 3); 367 + break; 368 + } 369 + } 370 + 336 371 static const struct dvb_tuner_ops stv6110x_ops = { 337 372 .info = { 338 373 .name = "STV6110(A) Silicon Tuner", ··· 377 342 .release = stv6110x_release 378 343 }; 379 344 380 - static const struct stv6110x_devctl stv6110x_ctl = { 345 + static struct stv6110x_devctl stv6110x_ctl = { 381 346 .tuner_init = stv6110x_init, 382 347 .tuner_sleep = stv6110x_sleep, 383 348 .tuner_set_mode = stv6110x_set_mode, ··· 391 356 .tuner_get_status = stv6110x_get_status, 392 357 }; 393 358 359 + static void stv6110x_set_frontend_opts(struct stv6110x_state *stv6110x) 360 + { 361 + stv6110x->frontend->tuner_priv = stv6110x; 362 + stv6110x->frontend->ops.tuner_ops = stv6110x_ops; 363 + } 364 + 365 + static struct stv6110x_devctl *stv6110x_get_devctl(struct i2c_client *client) 366 + { 367 + struct stv6110x_state *stv6110x = i2c_get_clientdata(client); 368 + 369 + dev_dbg(&client->dev, "\n"); 370 + 371 + return stv6110x->devctl; 372 + } 373 + 374 + static int stv6110x_probe(struct i2c_client *client, 375 + const struct i2c_device_id *id) 376 + { 377 + struct stv6110x_config *config = client->dev.platform_data; 378 + 379 + struct stv6110x_state *stv6110x; 380 + 381 + stv6110x = kzalloc(sizeof(*stv6110x), GFP_KERNEL); 382 + if (!stv6110x) 383 + return -ENOMEM; 384 + 385 + stv6110x->frontend = config->frontend; 386 + stv6110x->i2c = client->adapter; 387 + stv6110x->config = config; 388 + stv6110x->devctl = &stv6110x_ctl; 389 + 390 + st6110x_init_regs(stv6110x); 391 + stv6110x_setup_divider(stv6110x); 392 + stv6110x_set_frontend_opts(stv6110x); 393 + 394 + dev_info(&stv6110x->i2c->dev, "Probed STV6110x\n"); 395 + 396 + i2c_set_clientdata(client, stv6110x); 397 + 398 + /* setup callbacks */ 399 + config->get_devctl = stv6110x_get_devctl; 400 + 401 + return 0; 402 + } 403 + 404 + static int stv6110x_remove(struct i2c_client *client) 405 + { 406 + struct stv6110x_state *stv6110x = i2c_get_clientdata(client); 407 + 408 + stv6110x_release(stv6110x->frontend); 409 + return 0; 410 + } 411 + 394 412 const struct stv6110x_devctl *stv6110x_attach(struct dvb_frontend *fe, 395 413 const struct stv6110x_config *config, 396 414 struct i2c_adapter *i2c) 397 415 { 398 416 struct stv6110x_state *stv6110x; 399 - u8 default_regs[] = {0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e}; 400 417 401 - stv6110x = kzalloc(sizeof (struct stv6110x_state), GFP_KERNEL); 418 + stv6110x = kzalloc(sizeof(*stv6110x), GFP_KERNEL); 402 419 if (!stv6110x) 403 420 return NULL; 404 421 422 + stv6110x->frontend = fe; 405 423 stv6110x->i2c = i2c; 406 424 stv6110x->config = config; 407 425 stv6110x->devctl = &stv6110x_ctl; 408 - memcpy(stv6110x->regs, default_regs, 8); 409 426 410 - /* setup divider */ 411 - switch (stv6110x->config->clk_div) { 412 - default: 413 - case 1: 414 - STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 0); 415 - break; 416 - case 2: 417 - STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 1); 418 - break; 419 - case 4: 420 - STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 2); 421 - break; 422 - case 8: 423 - case 0: 424 - STV6110x_SETFIELD(stv6110x->regs[STV6110x_CTRL2], CTRL2_CO_DIV, 3); 425 - break; 426 - } 427 + st6110x_init_regs(stv6110x); 428 + stv6110x_setup_divider(stv6110x); 429 + stv6110x_set_frontend_opts(stv6110x); 427 430 428 431 fe->tuner_priv = stv6110x; 429 432 fe->ops.tuner_ops = stv6110x_ops; 430 433 431 - printk(KERN_INFO "%s: Attaching STV6110x\n", __func__); 434 + dev_info(&stv6110x->i2c->dev, "Attaching STV6110x\n"); 432 435 return stv6110x->devctl; 433 436 } 434 437 EXPORT_SYMBOL(stv6110x_attach); 438 + 439 + static const struct i2c_device_id stv6110x_id_table[] = { 440 + {"stv6110x", 0}, 441 + {} 442 + }; 443 + MODULE_DEVICE_TABLE(i2c, stv6110x_id_table); 444 + 445 + static struct i2c_driver stv6110x_driver = { 446 + .driver = { 447 + .name = "stv6110x", 448 + .suppress_bind_attrs = true, 449 + }, 450 + .probe = stv6110x_probe, 451 + .remove = stv6110x_remove, 452 + .id_table = stv6110x_id_table, 453 + }; 454 + 455 + module_i2c_driver(stv6110x_driver); 435 456 436 457 MODULE_AUTHOR("Manu Abraham"); 437 458 MODULE_DESCRIPTION("STV6110x Silicon tuner");
+3
drivers/media/dvb-frontends/stv6110x.h
··· 15 15 u8 addr; 16 16 u32 refclk; 17 17 u8 clk_div; /* divisor value for the output clock */ 18 + struct dvb_frontend *frontend; 19 + 20 + struct stv6110x_devctl* (*get_devctl)(struct i2c_client *i2c); 18 21 }; 19 22 20 23 enum tuner_mode {
+2 -1
drivers/media/dvb-frontends/stv6110x_priv.h
··· 54 54 #define REFCLOCK_MHz (stv6110x->config->refclk / 1000000) 55 55 56 56 struct stv6110x_state { 57 + struct dvb_frontend *frontend; 57 58 struct i2c_adapter *i2c; 58 59 const struct stv6110x_config *config; 59 60 u8 regs[8]; 60 61 61 - const struct stv6110x_devctl *devctl; 62 + struct stv6110x_devctl *devctl; 62 63 }; 63 64 64 65 #endif /* __STV6110x_PRIV_H */