* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+#include <linux/clk.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/interrupt.h>
struct resource *ioarea;
struct au1k_irda_platform_data *platdata;
+ struct clk *irda_clk;
};
static int qos_mtt_bits = 0x07; /* 1 ms or more */
static int au1k_init(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
- u32 enable, ring_address;
+ u32 enable, ring_address, phyck;
+ struct clk *c;
int i;
+ c = clk_get(NULL, "irda_clk");
+ if (IS_ERR(c))
+ return PTR_ERR(c);
+ i = clk_prepare_enable(c);
+ if (i) {
+ clk_put(c);
+ return i;
+ }
+
+ switch (clk_get_rate(c)) {
+ case 40000000:
+ phyck = IR_PHYCLK_40MHZ;
+ break;
+ case 48000000:
+ phyck = IR_PHYCLK_48MHZ;
+ break;
+ case 56000000:
+ phyck = IR_PHYCLK_56MHZ;
+ break;
+ case 64000000:
+ phyck = IR_PHYCLK_64MHZ;
+ break;
+ default:
+ clk_disable_unprepare(c);
+ clk_put(c);
+ return -EINVAL;
+ }
+ aup->irda_clk = c;
+
enable = IR_HC | IR_CE | IR_C;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
enable |= IR_BE;
irda_write(aup, IR_RING_SIZE,
(RING_SIZE_64 << 8) | (RING_SIZE_64 << 12));
- irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN);
+ irda_write(aup, IR_CONFIG_2, phyck | IR_ONE_PIN);
irda_write(aup, IR_RING_ADDR_CMPR, 0);
au1k_irda_set_speed(dev, 9600);
free_irq(aup->irq_tx, dev);
free_irq(aup->irq_rx, dev);
+ clk_disable_unprepare(aup->irda_clk);
+ clk_put(aup->irda_clk);
+
return 0;
}
struct au1k_private *aup;
struct net_device *dev;
struct resource *r;
+ struct clk *c;
int err;
dev = alloc_irdadev(sizeof(struct au1k_private));
if (!aup->ioarea)
goto out;
+ /* bail out early if clock doesn't exist */
+ c = clk_get(NULL, "irda_clk");
+ if (IS_ERR(c)) {
+ err = PTR_ERR(c);
+ goto out;
+ }
+ clk_put(c);
+
aup->iobase = ioremap_nocache(r->start, resource_size(r));
if (!aup->iobase)
goto out2;