si2157.c revision a83d7d17ad4c920b9b3f5330521fa346dddd3de3
1ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari/* 2ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * Silicon Labs Si2157 silicon tuner driver 3ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * 4ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * Copyright (C) 2014 Antti Palosaari <crope@iki.fi> 5ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * 6ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * This program is free software; you can redistribute it and/or modify 7ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * it under the terms of the GNU General Public License as published by 8ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * the Free Software Foundation; either version 2 of the License, or 9ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * (at your option) any later version. 10ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * 11ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * This program is distributed in the hope that it will be useful, 12ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * but WITHOUT ANY WARRANTY; without even the implied warranty of 13ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari * GNU General Public License for more details. 15ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari */ 16ba92ae0f83d415cb764f50cf4e47970011fbe2afAntti Palosaari 17930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari#include "si2157_priv.h" 18930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 19930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari/* execute firmware command */ 20930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_cmd_execute(struct si2157 *s, struct si2157_cmd *cmd) 21930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 22930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari int ret; 23930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari u8 buf[1]; 24930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari unsigned long timeout; 25930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 26930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari mutex_lock(&s->i2c_mutex); 27930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 28930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (cmd->len) { 29930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* write cmd and args for firmware */ 30930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = i2c_master_send(s->client, cmd->args, cmd->len); 31930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret < 0) { 32930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err_mutex_unlock; 33930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } else if (ret != cmd->len) { 34930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = -EREMOTEIO; 35930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err_mutex_unlock; 36930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 37930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 38930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 39930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* wait cmd execution terminate */ 40930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari #define TIMEOUT 80 41930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari timeout = jiffies + msecs_to_jiffies(TIMEOUT); 42930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari while (!time_after(jiffies, timeout)) { 43930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = i2c_master_recv(s->client, buf, 1); 44930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret < 0) { 45930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err_mutex_unlock; 46930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } else if (ret != 1) { 47930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = -EREMOTEIO; 48930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err_mutex_unlock; 49930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 50930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 51930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* firmware ready? */ 52930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if ((buf[0] >> 7) & 0x01) 53930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari break; 54930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 55930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 56930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n", __func__, 57930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari jiffies_to_msecs(jiffies) - 58930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari (jiffies_to_msecs(timeout) - TIMEOUT)); 59930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 60930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (!(buf[0] >> 7) & 0x01) { 61930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = -ETIMEDOUT; 62930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err_mutex_unlock; 63930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } else { 64930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = 0; 65930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 66930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 67930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarierr_mutex_unlock: 68930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari mutex_unlock(&s->i2c_mutex); 69930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 70930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 71930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 72930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 73930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarierr: 74930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 75930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return ret; 76930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 77930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 78930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_init(struct dvb_frontend *fe) 79930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 80930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s = fe->tuner_priv; 81930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 82930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, "%s:\n", __func__); 83930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 84930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s->active = true; 85930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 86930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 87930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 88930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 89930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_sleep(struct dvb_frontend *fe) 90930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 91930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s = fe->tuner_priv; 92a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari int ret; 93a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari struct si2157_cmd cmd; 94930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 95930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, "%s:\n", __func__); 96930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 97930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s->active = false; 98930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 99a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari memcpy(cmd.args, "\x13", 1); 100a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari cmd.len = 1; 101a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari ret = si2157_cmd_execute(s, &cmd); 102a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari if (ret) 103a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari goto err; 104a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari 105930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 106a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaarierr: 107a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 108a83d7d17ad4c920b9b3f5330521fa346dddd3de3Antti Palosaari return ret; 109930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 110930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 111930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_set_params(struct dvb_frontend *fe) 112930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 113930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s = fe->tuner_priv; 114930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct dtv_frontend_properties *c = &fe->dtv_property_cache; 115930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari int ret; 116930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157_cmd cmd; 117930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 118930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, 119930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari "%s: delivery_system=%d frequency=%u bandwidth_hz=%u\n", 120930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari __func__, c->delivery_system, c->frequency, 121930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari c->bandwidth_hz); 122930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 123930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (!s->active) { 124930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = -EAGAIN; 125930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 126930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 127930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 128930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* configure? */ 129930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[0] = 0xc0; 130930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[1] = 0x00; 131930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[2] = 0x0c; 132930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[3] = 0x00; 133930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[4] = 0x00; 134930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[5] = 0x01; 135930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[6] = 0x01; 136930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[7] = 0x01; 137930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[8] = 0x01; 138930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[9] = 0x01; 139930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[10] = 0x01; 140930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[11] = 0x02; 141930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[12] = 0x00; 142930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[13] = 0x00; 143930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[14] = 0x01; 144930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.len = 15; 145930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 146930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 147930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 148930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 149930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[0] = 0x02; 150930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.len = 1; 151930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 152930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 153930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 154930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 155930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[0] = 0x01; 156930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[1] = 0x01; 157930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.len = 2; 158930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 159930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 160930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 161930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 162930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* set frequency */ 163930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[0] = 0x41; 164930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[1] = 0x00; 165930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[2] = 0x00; 166930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[3] = 0x00; 167930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[4] = (c->frequency >> 0) & 0xff; 168930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[5] = (c->frequency >> 8) & 0xff; 169930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[6] = (c->frequency >> 16) & 0xff; 170930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.args[7] = (c->frequency >> 24) & 0xff; 171930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.len = 8; 172930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 173930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 174930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 175930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 176930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 177930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarierr: 178930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret); 179930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return ret; 180930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 181930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 182930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic const struct dvb_tuner_ops si2157_tuner_ops = { 183930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .info = { 184930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .name = "Silicon Labs Si2157", 185ae4c8919bb761c7f209fb260a82304a54616da0dAntti Palosaari .frequency_min = 110000000, 186930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .frequency_max = 862000000, 187930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari }, 188930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 189930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .init = si2157_init, 190930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .sleep = si2157_sleep, 191930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .set_params = si2157_set_params, 192930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari}; 193930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 194930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_probe(struct i2c_client *client, 195930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari const struct i2c_device_id *id) 196930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 197930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157_config *cfg = client->dev.platform_data; 198930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct dvb_frontend *fe = cfg->fe; 199930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s; 200930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157_cmd cmd; 201930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari int ret; 202930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 203930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s = kzalloc(sizeof(struct si2157), GFP_KERNEL); 204930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (!s) { 205930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = -ENOMEM; 206930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME); 207930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 208930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari } 209930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 210930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s->client = client; 211930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari s->fe = cfg->fe; 212930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari mutex_init(&s->i2c_mutex); 213930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 214930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari /* check if the tuner is there */ 215930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari cmd.len = 0; 216930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari ret = si2157_cmd_execute(s, &cmd); 217930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari if (ret) 218930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari goto err; 219930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 220930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari fe->tuner_priv = s; 221930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari memcpy(&fe->ops.tuner_ops, &si2157_tuner_ops, 222930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari sizeof(struct dvb_tuner_ops)); 223930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 224930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari i2c_set_clientdata(client, s); 225930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 226930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_info(&s->client->dev, 227930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari "%s: Silicon Labs Si2157 successfully attached\n", 228930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari KBUILD_MODNAME); 229930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 230930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarierr: 231930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret); 232930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari kfree(s); 233930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 234930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return ret; 235930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 236930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 237930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic int si2157_remove(struct i2c_client *client) 238930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari{ 239930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct si2157 *s = i2c_get_clientdata(client); 240930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari struct dvb_frontend *fe = s->fe; 241930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 242930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari dev_dbg(&client->dev, "%s:\n", __func__); 243930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 244930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops)); 245930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari fe->tuner_priv = NULL; 246930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari kfree(s); 247930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 248930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari return 0; 249930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari} 250930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 251930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic const struct i2c_device_id si2157_id[] = { 252930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari {"si2157", 0}, 253930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari {} 254930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari}; 255930a873081986393f6e7e0fb9275753c1485277bAntti PalosaariMODULE_DEVICE_TABLE(i2c, si2157_id); 256930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 257930a873081986393f6e7e0fb9275753c1485277bAntti Palosaaristatic struct i2c_driver si2157_driver = { 258930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .driver = { 259930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .owner = THIS_MODULE, 260930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .name = "si2157", 261930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari }, 262930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .probe = si2157_probe, 263930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .remove = si2157_remove, 264930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari .id_table = si2157_id, 265930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari}; 266930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 267930a873081986393f6e7e0fb9275753c1485277bAntti Palosaarimodule_i2c_driver(si2157_driver); 268930a873081986393f6e7e0fb9275753c1485277bAntti Palosaari 269930a873081986393f6e7e0fb9275753c1485277bAntti PalosaariMODULE_DESCRIPTION("Silicon Labs Si2157 silicon tuner driver"); 270930a873081986393f6e7e0fb9275753c1485277bAntti PalosaariMODULE_AUTHOR("Antti Palosaari <crope@iki.fi>"); 271930a873081986393f6e7e0fb9275753c1485277bAntti PalosaariMODULE_LICENSE("GPL"); 272