au0828-core.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. /*
  2. * Driver for the Auvitek USB bridge
  3. *
  4. * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. *
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21. #include "au0828.h"
  22. #include "au8522.h"
  23. #include <linux/module.h>
  24. #include <linux/slab.h>
  25. #include <linux/videodev2.h>
  26. #include <media/v4l2-common.h>
  27. #include <linux/mutex.h>
  28. /* Due to enum tuner_pad_index */
  29. #include <media/tuner.h>
  30. /*
  31. * 1 = General debug messages
  32. * 2 = USB handling
  33. * 4 = I2C related
  34. * 8 = Bridge related
  35. * 16 = IR related
  36. */
  37. int au0828_debug;
  38. module_param_named(debug, au0828_debug, int, 0644);
  39. MODULE_PARM_DESC(debug,
  40. "set debug bitmask: 1=general, 2=USB, 4=I2C, 8=bridge, 16=IR");
  41. static unsigned int disable_usb_speed_check;
  42. module_param(disable_usb_speed_check, int, 0444);
  43. MODULE_PARM_DESC(disable_usb_speed_check,
  44. "override min bandwidth requirement of 480M bps");
  45. #define _AU0828_BULKPIPE 0x03
  46. #define _BULKPIPESIZE 0xffff
  47. static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
  48. u16 index);
  49. static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
  50. u16 index, unsigned char *cp, u16 size);
  51. /* USB Direction */
  52. #define CMD_REQUEST_IN 0x00
  53. #define CMD_REQUEST_OUT 0x01
  54. u32 au0828_readreg(struct au0828_dev *dev, u16 reg)
  55. {
  56. u8 result = 0;
  57. recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, &result, 1);
  58. dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, result);
  59. return result;
  60. }
  61. u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val)
  62. {
  63. dprintk(8, "%s(0x%04x, 0x%02x)\n", __func__, reg, val);
  64. return send_control_msg(dev, CMD_REQUEST_OUT, val, reg);
  65. }
  66. static int send_control_msg(struct au0828_dev *dev, u16 request, u32 value,
  67. u16 index)
  68. {
  69. int status = -ENODEV;
  70. if (dev->usbdev) {
  71. /* cp must be memory that has been allocated by kmalloc */
  72. status = usb_control_msg(dev->usbdev,
  73. usb_sndctrlpipe(dev->usbdev, 0),
  74. request,
  75. USB_DIR_OUT | USB_TYPE_VENDOR |
  76. USB_RECIP_DEVICE,
  77. value, index, NULL, 0, 1000);
  78. status = min(status, 0);
  79. if (status < 0) {
  80. pr_err("%s() Failed sending control message, error %d.\n",
  81. __func__, status);
  82. }
  83. }
  84. return status;
  85. }
  86. static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
  87. u16 index, unsigned char *cp, u16 size)
  88. {
  89. int status = -ENODEV;
  90. mutex_lock(&dev->mutex);
  91. if (dev->usbdev) {
  92. status = usb_control_msg(dev->usbdev,
  93. usb_rcvctrlpipe(dev->usbdev, 0),
  94. request,
  95. USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
  96. value, index,
  97. dev->ctrlmsg, size, 1000);
  98. status = min(status, 0);
  99. if (status < 0) {
  100. pr_err("%s() Failed receiving control message, error %d.\n",
  101. __func__, status);
  102. }
  103. /* the host controller requires heap allocated memory, which
  104. is why we didn't just pass "cp" into usb_control_msg */
  105. memcpy(cp, dev->ctrlmsg, size);
  106. }
  107. mutex_unlock(&dev->mutex);
  108. return status;
  109. }
  110. #ifdef CONFIG_MEDIA_CONTROLLER
  111. static void au0828_media_graph_notify(struct media_entity *new,
  112. void *notify_data);
  113. #endif
  114. static void au0828_unregister_media_device(struct au0828_dev *dev)
  115. {
  116. #ifdef CONFIG_MEDIA_CONTROLLER
  117. struct media_device *mdev = dev->media_dev;
  118. struct media_entity_notify *notify, *nextp;
  119. if (!mdev || !media_devnode_is_registered(mdev->devnode))
  120. return;
  121. /* Remove au0828 entity_notify callbacks */
  122. list_for_each_entry_safe(notify, nextp, &mdev->entity_notify, list) {
  123. if (notify->notify != au0828_media_graph_notify)
  124. continue;
  125. media_device_unregister_entity_notify(mdev, notify);
  126. }
  127. /* clear enable_source, disable_source */
  128. dev->media_dev->source_priv = NULL;
  129. dev->media_dev->enable_source = NULL;
  130. dev->media_dev->disable_source = NULL;
  131. media_device_unregister(dev->media_dev);
  132. media_device_cleanup(dev->media_dev);
  133. kfree(dev->media_dev);
  134. dev->media_dev = NULL;
  135. #endif
  136. }
  137. void au0828_usb_release(struct au0828_dev *dev)
  138. {
  139. au0828_unregister_media_device(dev);
  140. /* I2C */
  141. au0828_i2c_unregister(dev);
  142. kfree(dev);
  143. }
  144. static void au0828_usb_disconnect(struct usb_interface *interface)
  145. {
  146. struct au0828_dev *dev = usb_get_intfdata(interface);
  147. dprintk(1, "%s()\n", __func__);
  148. /* there is a small window after disconnect, before
  149. dev->usbdev is NULL, for poll (e.g: IR) try to access
  150. the device and fill the dmesg with error messages.
  151. Set the status so poll routines can check and avoid
  152. access after disconnect.
  153. */
  154. set_bit(DEV_DISCONNECTED, &dev->dev_state);
  155. au0828_rc_unregister(dev);
  156. /* Digital TV */
  157. au0828_dvb_unregister(dev);
  158. usb_set_intfdata(interface, NULL);
  159. mutex_lock(&dev->mutex);
  160. dev->usbdev = NULL;
  161. mutex_unlock(&dev->mutex);
  162. if (au0828_analog_unregister(dev)) {
  163. /*
  164. * No need to call au0828_usb_release() if V4L2 is enabled,
  165. * as this is already called via au0828_usb_v4l2_release()
  166. */
  167. return;
  168. }
  169. au0828_usb_release(dev);
  170. }
  171. static int au0828_media_device_init(struct au0828_dev *dev,
  172. struct usb_device *udev)
  173. {
  174. #ifdef CONFIG_MEDIA_CONTROLLER
  175. struct media_device *mdev;
  176. mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
  177. if (!mdev)
  178. return -ENOMEM;
  179. /* check if media device is already initialized */
  180. if (!mdev->dev)
  181. media_device_usb_init(mdev, udev, udev->product);
  182. dev->media_dev = mdev;
  183. #endif
  184. return 0;
  185. }
  186. #ifdef CONFIG_MEDIA_CONTROLLER
  187. static void au0828_media_graph_notify(struct media_entity *new,
  188. void *notify_data)
  189. {
  190. struct au0828_dev *dev = (struct au0828_dev *) notify_data;
  191. int ret;
  192. struct media_entity *entity, *mixer = NULL, *decoder = NULL;
  193. if (!new) {
  194. /*
  195. * Called during au0828 probe time to connect
  196. * entites that were created prior to registering
  197. * the notify handler. Find mixer and decoder.
  198. */
  199. media_device_for_each_entity(entity, dev->media_dev) {
  200. if (entity->function == MEDIA_ENT_F_AUDIO_MIXER)
  201. mixer = entity;
  202. else if (entity->function == MEDIA_ENT_F_ATV_DECODER)
  203. decoder = entity;
  204. }
  205. goto create_link;
  206. }
  207. switch (new->function) {
  208. case MEDIA_ENT_F_AUDIO_MIXER:
  209. mixer = new;
  210. if (dev->decoder)
  211. decoder = dev->decoder;
  212. break;
  213. case MEDIA_ENT_F_ATV_DECODER:
  214. /* In case, Mixer is added first, find mixer and create link */
  215. media_device_for_each_entity(entity, dev->media_dev) {
  216. if (entity->function == MEDIA_ENT_F_AUDIO_MIXER)
  217. mixer = entity;
  218. }
  219. decoder = new;
  220. break;
  221. default:
  222. break;
  223. }
  224. create_link:
  225. if (decoder && mixer) {
  226. ret = media_create_pad_link(decoder,
  227. DEMOD_PAD_AUDIO_OUT,
  228. mixer, 0,
  229. MEDIA_LNK_FL_ENABLED);
  230. if (ret)
  231. dev_err(&dev->usbdev->dev,
  232. "Mixer Pad Link Create Error: %d\n", ret);
  233. }
  234. }
  235. static int au0828_enable_source(struct media_entity *entity,
  236. struct media_pipeline *pipe)
  237. {
  238. struct media_entity *source, *find_source;
  239. struct media_entity *sink;
  240. struct media_link *link, *found_link = NULL;
  241. int ret = 0;
  242. struct media_device *mdev = entity->graph_obj.mdev;
  243. struct au0828_dev *dev;
  244. if (!mdev)
  245. return -ENODEV;
  246. mutex_lock(&mdev->graph_mutex);
  247. dev = mdev->source_priv;
  248. /*
  249. * For Audio and V4L2 entity, find the link to which decoder
  250. * is the sink. Look for an active link between decoder and
  251. * source (tuner/s-video/Composite), if one exists, nothing
  252. * to do. If not, look for any active links between source
  253. * and any other entity. If one exists, source is busy. If
  254. * source is free, setup link and start pipeline from source.
  255. * For DVB FE entity, the source for the link is the tuner.
  256. * Check if tuner is available and setup link and start
  257. * pipeline.
  258. */
  259. if (entity->function == MEDIA_ENT_F_DTV_DEMOD) {
  260. sink = entity;
  261. find_source = dev->tuner;
  262. } else {
  263. /* Analog isn't configured or register failed */
  264. if (!dev->decoder) {
  265. ret = -ENODEV;
  266. goto end;
  267. }
  268. sink = dev->decoder;
  269. /*
  270. * Default input is tuner and default input_type
  271. * is AU0828_VMUX_TELEVISION.
  272. * FIXME:
  273. * There is a problem when s_input is called to
  274. * change the default input. s_input will try to
  275. * enable_source before attempting to change the
  276. * input on the device, and will end up enabling
  277. * default source which is tuner.
  278. *
  279. * Additional logic is necessary in au0828
  280. * to detect that the input has changed and
  281. * enable the right source.
  282. */
  283. if (dev->input_type == AU0828_VMUX_TELEVISION)
  284. find_source = dev->tuner;
  285. else if (dev->input_type == AU0828_VMUX_SVIDEO ||
  286. dev->input_type == AU0828_VMUX_COMPOSITE)
  287. find_source = &dev->input_ent[dev->input_type];
  288. else {
  289. /* unknown input - let user select input */
  290. ret = 0;
  291. goto end;
  292. }
  293. }
  294. /* Is an active link between sink and source */
  295. if (dev->active_link) {
  296. /*
  297. * If DVB is using the tuner and calling entity is
  298. * audio/video, the following check will be false,
  299. * since sink is different. Result is Busy.
  300. */
  301. if (dev->active_link->sink->entity == sink &&
  302. dev->active_link->source->entity == find_source) {
  303. /*
  304. * Either ALSA or Video own tuner. sink is
  305. * the same for both. Prevent Video stepping
  306. * on ALSA when ALSA owns the source.
  307. */
  308. if (dev->active_link_owner != entity &&
  309. dev->active_link_owner->function ==
  310. MEDIA_ENT_F_AUDIO_CAPTURE) {
  311. pr_debug("ALSA has the tuner\n");
  312. ret = -EBUSY;
  313. goto end;
  314. }
  315. ret = 0;
  316. goto end;
  317. } else {
  318. ret = -EBUSY;
  319. goto end;
  320. }
  321. }
  322. list_for_each_entry(link, &sink->links, list) {
  323. /* Check sink, and source */
  324. if (link->sink->entity == sink &&
  325. link->source->entity == find_source) {
  326. found_link = link;
  327. break;
  328. }
  329. }
  330. if (!found_link) {
  331. ret = -ENODEV;
  332. goto end;
  333. }
  334. /* activate link between source and sink and start pipeline */
  335. source = found_link->source->entity;
  336. ret = __media_entity_setup_link(found_link, MEDIA_LNK_FL_ENABLED);
  337. if (ret) {
  338. pr_err("Activate tuner link %s->%s. Error %d\n",
  339. source->name, sink->name, ret);
  340. goto end;
  341. }
  342. ret = __media_entity_pipeline_start(entity, pipe);
  343. if (ret) {
  344. pr_err("Start Pipeline: %s->%s Error %d\n",
  345. source->name, entity->name, ret);
  346. ret = __media_entity_setup_link(found_link, 0);
  347. pr_err("Deactivate link Error %d\n", ret);
  348. goto end;
  349. }
  350. /*
  351. * save active link and active link owner to avoid audio
  352. * deactivating video owned link from disable_source and
  353. * vice versa
  354. */
  355. dev->active_link = found_link;
  356. dev->active_link_owner = entity;
  357. dev->active_source = source;
  358. dev->active_sink = sink;
  359. pr_debug("Enabled Source: %s->%s->%s Ret %d\n",
  360. dev->active_source->name, dev->active_sink->name,
  361. dev->active_link_owner->name, ret);
  362. end:
  363. mutex_unlock(&mdev->graph_mutex);
  364. pr_debug("au0828_enable_source() end %s %d %d\n",
  365. entity->name, entity->function, ret);
  366. return ret;
  367. }
  368. static void au0828_disable_source(struct media_entity *entity)
  369. {
  370. int ret = 0;
  371. struct media_device *mdev = entity->graph_obj.mdev;
  372. struct au0828_dev *dev;
  373. if (!mdev)
  374. return;
  375. mutex_lock(&mdev->graph_mutex);
  376. dev = mdev->source_priv;
  377. if (!dev->active_link) {
  378. ret = -ENODEV;
  379. goto end;
  380. }
  381. /* link is active - stop pipeline from source (tuner) */
  382. if (dev->active_link->sink->entity == dev->active_sink &&
  383. dev->active_link->source->entity == dev->active_source) {
  384. /*
  385. * prevent video from deactivating link when audio
  386. * has active pipeline
  387. */
  388. if (dev->active_link_owner != entity)
  389. goto end;
  390. __media_entity_pipeline_stop(entity);
  391. ret = __media_entity_setup_link(dev->active_link, 0);
  392. if (ret)
  393. pr_err("Deactivate link Error %d\n", ret);
  394. pr_debug("Disabled Source: %s->%s->%s Ret %d\n",
  395. dev->active_source->name, dev->active_sink->name,
  396. dev->active_link_owner->name, ret);
  397. dev->active_link = NULL;
  398. dev->active_link_owner = NULL;
  399. dev->active_source = NULL;
  400. dev->active_sink = NULL;
  401. }
  402. end:
  403. mutex_unlock(&mdev->graph_mutex);
  404. }
  405. #endif
  406. static int au0828_media_device_register(struct au0828_dev *dev,
  407. struct usb_device *udev)
  408. {
  409. #ifdef CONFIG_MEDIA_CONTROLLER
  410. int ret;
  411. struct media_entity *entity, *demod = NULL;
  412. struct media_link *link;
  413. if (!dev->media_dev)
  414. return 0;
  415. if (!media_devnode_is_registered(dev->media_dev->devnode)) {
  416. /* register media device */
  417. ret = media_device_register(dev->media_dev);
  418. if (ret) {
  419. dev_err(&udev->dev,
  420. "Media Device Register Error: %d\n", ret);
  421. return ret;
  422. }
  423. } else {
  424. /*
  425. * Call au0828_media_graph_notify() to connect
  426. * audio graph to our graph. In this case, audio
  427. * driver registered the device and there is no
  428. * entity_notify to be called when new entities
  429. * are added. Invoke it now.
  430. */
  431. au0828_media_graph_notify(NULL, (void *) dev);
  432. }
  433. /*
  434. * Find tuner, decoder and demod.
  435. *
  436. * The tuner and decoder should be cached, as they'll be used by
  437. * au0828_enable_source.
  438. *
  439. * It also needs to disable the link between tuner and
  440. * decoder/demod, to avoid disable step when tuner is requested
  441. * by video or audio. Note that this step can't be done until dvb
  442. * graph is created during dvb register.
  443. */
  444. media_device_for_each_entity(entity, dev->media_dev) {
  445. switch (entity->function) {
  446. case MEDIA_ENT_F_TUNER:
  447. dev->tuner = entity;
  448. break;
  449. case MEDIA_ENT_F_ATV_DECODER:
  450. dev->decoder = entity;
  451. break;
  452. case MEDIA_ENT_F_DTV_DEMOD:
  453. demod = entity;
  454. break;
  455. }
  456. }
  457. /* Disable link between tuner->demod and/or tuner->decoder */
  458. if (dev->tuner) {
  459. list_for_each_entry(link, &dev->tuner->links, list) {
  460. if (demod && link->sink->entity == demod)
  461. media_entity_setup_link(link, 0);
  462. if (dev->decoder && link->sink->entity == dev->decoder)
  463. media_entity_setup_link(link, 0);
  464. }
  465. }
  466. /* register entity_notify callback */
  467. dev->entity_notify.notify_data = (void *) dev;
  468. dev->entity_notify.notify = (void *) au0828_media_graph_notify;
  469. ret = media_device_register_entity_notify(dev->media_dev,
  470. &dev->entity_notify);
  471. if (ret) {
  472. dev_err(&udev->dev,
  473. "Media Device register entity_notify Error: %d\n",
  474. ret);
  475. return ret;
  476. }
  477. /* set enable_source */
  478. dev->media_dev->source_priv = (void *) dev;
  479. dev->media_dev->enable_source = au0828_enable_source;
  480. dev->media_dev->disable_source = au0828_disable_source;
  481. #endif
  482. return 0;
  483. }
  484. static int au0828_usb_probe(struct usb_interface *interface,
  485. const struct usb_device_id *id)
  486. {
  487. int ifnum;
  488. int retval = 0;
  489. struct au0828_dev *dev;
  490. struct usb_device *usbdev = interface_to_usbdev(interface);
  491. ifnum = interface->altsetting->desc.bInterfaceNumber;
  492. if (ifnum != 0)
  493. return -ENODEV;
  494. dprintk(1, "%s() vendor id 0x%x device id 0x%x ifnum:%d\n", __func__,
  495. le16_to_cpu(usbdev->descriptor.idVendor),
  496. le16_to_cpu(usbdev->descriptor.idProduct),
  497. ifnum);
  498. /*
  499. * Make sure we have 480 Mbps of bandwidth, otherwise things like
  500. * video stream wouldn't likely work, since 12 Mbps is generally
  501. * not enough even for most Digital TV streams.
  502. */
  503. if (usbdev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) {
  504. pr_err("au0828: Device initialization failed.\n");
  505. pr_err("au0828: Device must be connected to a high-speed USB 2.0 port.\n");
  506. return -ENODEV;
  507. }
  508. dev = kzalloc(sizeof(*dev), GFP_KERNEL);
  509. if (dev == NULL) {
  510. pr_err("%s() Unable to allocate memory\n", __func__);
  511. return -ENOMEM;
  512. }
  513. mutex_init(&dev->lock);
  514. mutex_lock(&dev->lock);
  515. mutex_init(&dev->mutex);
  516. mutex_init(&dev->dvb.lock);
  517. dev->usbdev = usbdev;
  518. dev->boardnr = id->driver_info;
  519. dev->board = au0828_boards[dev->boardnr];
  520. /* Initialize the media controller */
  521. retval = au0828_media_device_init(dev, usbdev);
  522. if (retval) {
  523. pr_err("%s() au0828_media_device_init failed\n",
  524. __func__);
  525. mutex_unlock(&dev->lock);
  526. kfree(dev);
  527. return retval;
  528. }
  529. retval = au0828_v4l2_device_register(interface, dev);
  530. if (retval) {
  531. au0828_usb_v4l2_media_release(dev);
  532. mutex_unlock(&dev->lock);
  533. kfree(dev);
  534. return retval;
  535. }
  536. /* Power Up the bridge */
  537. au0828_write(dev, REG_600, 1 << 4);
  538. /* Bring up the GPIO's and supporting devices */
  539. au0828_gpio_setup(dev);
  540. /* I2C */
  541. au0828_i2c_register(dev);
  542. /* Setup */
  543. au0828_card_setup(dev);
  544. /* Analog TV */
  545. retval = au0828_analog_register(dev, interface);
  546. if (retval) {
  547. pr_err("%s() au0282_dev_register failed to register on V4L2\n",
  548. __func__);
  549. goto done;
  550. }
  551. /* Digital TV */
  552. retval = au0828_dvb_register(dev);
  553. if (retval)
  554. pr_err("%s() au0282_dev_register failed\n",
  555. __func__);
  556. /* Remote controller */
  557. au0828_rc_register(dev);
  558. /*
  559. * Store the pointer to the au0828_dev so it can be accessed in
  560. * au0828_usb_disconnect
  561. */
  562. usb_set_intfdata(interface, dev);
  563. pr_info("Registered device AU0828 [%s]\n",
  564. dev->board.name == NULL ? "Unset" : dev->board.name);
  565. mutex_unlock(&dev->lock);
  566. retval = au0828_media_device_register(dev, usbdev);
  567. done:
  568. if (retval < 0)
  569. au0828_usb_disconnect(interface);
  570. return retval;
  571. }
  572. static int au0828_suspend(struct usb_interface *interface,
  573. pm_message_t message)
  574. {
  575. struct au0828_dev *dev = usb_get_intfdata(interface);
  576. if (!dev)
  577. return 0;
  578. pr_info("Suspend\n");
  579. au0828_rc_suspend(dev);
  580. au0828_v4l2_suspend(dev);
  581. au0828_dvb_suspend(dev);
  582. /* FIXME: should suspend also ATV/DTV */
  583. return 0;
  584. }
  585. static int au0828_resume(struct usb_interface *interface)
  586. {
  587. struct au0828_dev *dev = usb_get_intfdata(interface);
  588. if (!dev)
  589. return 0;
  590. pr_info("Resume\n");
  591. /* Power Up the bridge */
  592. au0828_write(dev, REG_600, 1 << 4);
  593. /* Bring up the GPIO's and supporting devices */
  594. au0828_gpio_setup(dev);
  595. au0828_rc_resume(dev);
  596. au0828_v4l2_resume(dev);
  597. au0828_dvb_resume(dev);
  598. /* FIXME: should resume also ATV/DTV */
  599. return 0;
  600. }
  601. static struct usb_driver au0828_usb_driver = {
  602. .name = KBUILD_MODNAME,
  603. .probe = au0828_usb_probe,
  604. .disconnect = au0828_usb_disconnect,
  605. .id_table = au0828_usb_id_table,
  606. .suspend = au0828_suspend,
  607. .resume = au0828_resume,
  608. .reset_resume = au0828_resume,
  609. };
  610. static int __init au0828_init(void)
  611. {
  612. int ret;
  613. if (au0828_debug & 1)
  614. pr_info("%s() Debugging is enabled\n", __func__);
  615. if (au0828_debug & 2)
  616. pr_info("%s() USB Debugging is enabled\n", __func__);
  617. if (au0828_debug & 4)
  618. pr_info("%s() I2C Debugging is enabled\n", __func__);
  619. if (au0828_debug & 8)
  620. pr_info("%s() Bridge Debugging is enabled\n",
  621. __func__);
  622. if (au0828_debug & 16)
  623. pr_info("%s() IR Debugging is enabled\n",
  624. __func__);
  625. pr_info("au0828 driver loaded\n");
  626. ret = usb_register(&au0828_usb_driver);
  627. if (ret)
  628. pr_err("usb_register failed, error = %d\n", ret);
  629. return ret;
  630. }
  631. static void __exit au0828_exit(void)
  632. {
  633. usb_deregister(&au0828_usb_driver);
  634. }
  635. module_init(au0828_init);
  636. module_exit(au0828_exit);
  637. MODULE_DESCRIPTION("Driver for Auvitek AU0828 based products");
  638. MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
  639. MODULE_LICENSE("GPL");
  640. MODULE_VERSION("0.0.3");